react核心概念-組件事件

[傳送門](事件處理 – React (reactjs.org))

組件與事件綁定

本章包含以下內(nèi)容:

  • React 中的組件
  • 為組件綁定事件
  • this 的指向
  • 向事件處理函數(shù)傳參

React 中的組件

React 中,可以使用類的方式來聲明一個(gè)組件。

class 類名 extends React.Component{
  render(){
    return (
        // 一段 JSX
    )
  }
}

除了類組件,React 中還支持使用函數(shù)來創(chuàng)建組件,同樣需要返回一段 JSX,來表示這個(gè)組件的 UI 是什么樣的。

function 組件名(){
  return (
    // 一段 JSX
  );
}

早期的函數(shù)組件被稱之為無狀態(tài)組件,一般僅僅用來做純 UI 的展示,里面不會(huì)有復(fù)雜的邏輯。

但是從 React 16.8 推出 Hooks 后,現(xiàn)在更多的是使用函數(shù)組件了。

這不僅僅是語法的改變,同時(shí)也代表著整個(gè) React 編程思想的一種轉(zhuǎn)變。

為組件綁定事件

React 中綁定事件的寫法如下:

<button onClick={activateLasers}>Activate Lasers</button>

React 中無法通過 return false 來阻止默認(rèn)行為,所以只有使用 e.preventDefault 的方式來阻止默認(rèn)行為。

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

如果是類組件,那么事件處理函數(shù)寫作一個(gè)類方法。

class Welcome extends React.Component {
  // 事件處理函數(shù)
  eventHandler(e){
    window.alert('Hello');
    e.preventDefault();
  }
  
  render() {
    return (
      <a  onClick={this.eventHandler}>this is a test</a>
    );
  }
}

React 的事件處理函數(shù)中所傳入的事件對象,是一個(gè)合成事件對象。

React 也提供了訪問原生事件對象的方式。如下:

eventHandler(e){
    e.nativeEvent // 原生事件對象
}

this 的指向

在react的類組件中,通過以下方法調(diào)用函數(shù),this的值將會(huì)指向undefined

import React, { Component } from 'react'
//改變this指向
export default class ClassComp extends Component {
    clickHandle(){
        console.log(this);//這里打印出來是undefined
    }
  render() {
    return (
      <div>
        {/* <a  onClick={(e)=>{e.preventDefault()}}>百度一下,你就知道了</a> */}
        <button onClick={this.clickHandle}>按鈕</button>
      </div>
    )
  }
}

但這并不是react的問題,而是由于 JSthis 的特殊性,事件處理函數(shù)中的 this 并不會(huì)指向當(dāng)前的組件,這就需要我們自行對 this 進(jìn)行指向的修正。

這里介紹 3 種解決方式:

  • 將事件處理函數(shù)修改為箭頭函數(shù)
  • 將事件綁定修改為箭頭函數(shù)
  • 使用 bind 方法來強(qiáng)制綁定 this 的指向

針對以上三種解決方法,現(xiàn)分別舉例如下:

方法一:將事件處理函數(shù)修改為箭頭函數(shù)
import React, { Component } from 'react'
//改變this指向
export default class ClassComp extends Component {
     clickHandle=()=>{
        console.log(this);//現(xiàn)在在瀏覽器中就會(huì)打印出當(dāng)前組件實(shí)例
    }
  render() {
    return (
      <div>
        {/* <a  onClick={(e)=>{e.preventDefault()}}>百度一下,你就知道了</a> */}
        <button onClick={this.clickHandle}>按鈕</button>
      </div>
    )
  }
}

方法二:將事件綁定修改為箭頭函數(shù)
import React, { Component } from 'react'
//改變this指向
export default class ClassComp extends Component {
    clickHandle(){
        console.log(this);//現(xiàn)在在瀏覽器中就會(huì)打印出當(dāng)前組件實(shí)例
    }
  render() {
    return (
      <div>
        {/* <a  onClick={(e)=>{e.preventDefault()}}>百度一下,你就知道了</a> */}
        <button onClick={()=>this.clickHandle()}>按鈕</button>
      </div>
    )
  }
}

import React, { Component } from 'react'
//改變this指向
export default class ClassComp extends Component {
    clickHandle(){
        console.log(this);//現(xiàn)在在瀏覽器中就會(huì)打印出當(dāng)前組件實(shí)例
    }
  render() {
    return (
      <div>
        {/* <a  onClick={(e)=>{e.preventDefault()}}>百度一下,你就知道了</a> */}
        <button onClick={()=>this.clickHandle()}>按鈕</button>
      </div>
    )
  }
}

方法三:使用 bind 方法來強(qiáng)制綁定 this 的指向
import React, { Component } from "react";
export default class ClassComp extends Component {
  constructor(props) {
    super(props);

    this.clickHandle = this.clickHandle.bind(this);
  }
  clickHandle() {
    console.log(this);
  }
  render() {
    return (
      <div>
        {/* <a  onClick={(e)=>{e.preventDefault()}}>百度一下,你就知道了</a> */}
        <button onClick={this.clickHandle}>按鈕</button>
      </div>
    );
  }
}

向事件處理程序傳參

另外還有一個(gè)非常重要的問題,就是如何向事件處理函數(shù)傳遞參數(shù)。

如果要傳遞參數(shù),可以使用下面的兩種方式來進(jìn)行傳參:

  • 通過 bind 方法在綁定 this 指向時(shí)向事件處理函數(shù)進(jìn)行傳參
  • 綁定事件時(shí),通過書寫箭頭函數(shù)的形式來傳參

舉例來說:
案例一:綁定事件時(shí),通過書寫箭頭函數(shù)的形式來傳參

import React, { Component } from "react";

export default class ClassComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        { id: 1, name: "lisi", age: 18 },
        { id: 2, name: "lisi2", age: 18 },
        { id: 3, name: "lisi3", age: 18 },
      ],
    };
  }
  deleteRow(id, e) {
    this.setState((prevState) => ({
      list: prevState.list.filter((item) => item.id !== id),
    }));
  }
  render() {
    return (
      <ul>
        {this.state.list.map((item) => (
          <li key={item.id}>
            {item.name}

            <button
              onClick={()=>this.deleteRow(item.id)}
            >
              刪除
            </button>
          </li>
        ))}
      </ul>
    );
  }
}

案例二:通過 bind 方法在綁定 this 指向時(shí)向事件處理函數(shù)進(jìn)行傳參

import React, { Component } from "react";

export default class ClassComp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [
        { id: 1, name: "lisi", age: 18 },
        { id: 2, name: "lisi2", age: 18 },
        { id: 3, name: "lisi3", age: 18 },
      ],
    };
  }

  deleteRow(id) {
    // 使用prevState參數(shù)基于前一個(gè)狀態(tài)來更新list,過濾掉要?jiǎng)h除的項(xiàng)
    this.setState((prevState) => ({
      list: prevState.list.filter((item) => item.id !== id),
    }));
  }

  render() {
    return (
      <ul>
        {this.state.list.map((item) => (
          <li key={item.id}>
            {item.name}
            {/* 使用bind來綁定函數(shù)并傳參,注意這里要返回一個(gè)新的函數(shù) */}
            <button onClick={this.deleteRow.bind(this, item.id)}>刪除</button>
          </li>
        ))}
      </ul>
    );
  }
}

今天的筆記就寫到這里了,每天進(jìn)步一小步,日積月累,水滴石穿

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容