react 中事件處理函數(shù)中this指向問題

我們知道,在 react 中,事件處理函數(shù)中的this很容易丟失,如:

class App extends React.Component {
  handleClick() {
    console.log(this);// undefined 
  }
  render() {
    return <div onClick={this.handleClick} >點(diǎn)我</div>;
  }
}

有4種this指向的解決方案 , 如下:

  1. 箭頭函數(shù)
  2. 構(gòu)造函數(shù)中的 bind
  3. 事件綁定時(shí)的 bind
  4. 事件綁定時(shí)的匿名函數(shù)+箭頭函數(shù)。

下邊我們分別給出它們的實(shí)現(xiàn)

箭頭函數(shù)

class App extends React.Component {
  // 修改為箭頭函數(shù)
  handleClick = () => {
    console.log(this);// 正常 
  }
  render() {
    return <div onClick={this.handleClick} >點(diǎn)擊</div>;
  }
}

構(gòu)造函數(shù)中的bind

class App extends React.Component {
  constructor(props) {
    super();
    // 通過bind 改寫this指向并返回新的函數(shù)
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log(this);// 正常
  }
  render() {
    // bind
    return <div onClick={this.handleClick} >點(diǎn)擊</div>;
  }
}

事件綁定時(shí)的bind

class App extends React.Component {
  handleClick() {
    console.log(this);// 正常
  }
  render() {
    // bind
    return <div onClick={this.handleClick.bind(this)} >點(diǎn)擊</div>;
  }
}

如需傳遞參數(shù),如下:

class App extends React.Component {
  handleClick(a, b, e) {
    console.log(this);// 正常
    console.log(a, b, e);// "aa","bb","事件對(duì)象"
  }
  render() {
    return <>
      <div onClick={this.handleClick.bind(this, "aa", "bb")} >點(diǎn)擊</div>
    </>
  }
}

事件綁定時(shí)的匿名函數(shù)+箭頭函數(shù)

class App extends React.Component {
  handleClick(e) {
    console.log(this);// 正常
  }
  render() {
    // bind
    return <div onClick={() => this.handleClick()} >點(diǎn)擊</div>;
  }
}

如需傳遞參數(shù),如下:

class App extends React.Component {
  handleClick(a, b, e) {
    console.log(this);// 正常
    console.log(a, b, e);// "aa","bb","事件對(duì)象"
  }
  render() {
    // bind
    return <div onClick={(e) => this.handleClick('aa', 'bb', e)} >點(diǎn)擊</div>;
  }
}

另外, 也可自定義屬性,如下:

class App extends React.Component {
  handleClick(e) {
    console.log(this);// 正常
    console.log(e.target.dataset.msg);// "aa"
  }
  render() {
    return <>
      <div data-msg="aa" onClick={this.handleClick.bind(this)} >點(diǎn)擊</div>
    </>
  }
}

但是,如果從性能角度出發(fā),只推薦一種: 事件綁定時(shí)的bind

this指向解決方案的性能比較
以下比較,主要從 實(shí)例成員函數(shù)能否得到復(fù)用觸發(fā),那么我們可以將其函數(shù)成員做對(duì)比,看哪種方式是共享內(nèi)存。

class App extends React.Component {
  constructor() {
    super();
    this.ref1 = React.createRef();
    this.ref2 = React.createRef();
  }

  handleClick(e) { 
    console.log(this.ref1.current.showBtn === this.ref2.current.showBtn);
  }
  render() {
    return <>
      <div onClick={this.handleClick.bind(this)} >
        <Btn ref={this.ref1} />
        <Btn ref={this.ref2} />
      </div>
    </>
  }
}

1. 箭頭函數(shù)

class Btn extends React.Component {
  showBtn = () => {
    console.log(this);
  }
  render() {
    return <button onClick={this.showBtn}>點(diǎn)擊</button>;
  }
}

結(jié)果如下:

  handleClick(e) { 
    console.log(this.ref1.current.showBtn === this.ref2.current.showBtn);// false
  }

說明:箭頭函數(shù)不靠譜

2. 構(gòu)造函數(shù)中的 bind

class Btn extends React.Component {
  constructor() {
    super();
    this.showBtn = this.showBtn.bind(this);
  }
  showBtn() {
    console.log(this);
  }
  render() {
    return <button onClick={this.showBtn}>點(diǎn)擊</button>;
  }
}

結(jié)果如下:

  handleClick(e) { 
    console.log(this.ref1.current.showBtn === this.ref2.current.showBtn); // false
  }

說明:構(gòu)造函數(shù)中的 bind不靠譜

3. 事件綁定時(shí)的 bind

class Btn extends React.Component { 
  showBtn() {
    console.log(this);
  }
  render() {
    return <button onClick={this.showBtn.bind(this)}>點(diǎn)擊</button>;
  }
}

結(jié)果如下:

  handleClick(e) { 
    console.log(this.ref1.current.showBtn === this.ref2.current.showBtn); // true
  }

說明:事件綁定時(shí)的 bind 靠譜!

**4. 事件綁定時(shí)的匿名函數(shù)+箭頭函數(shù) **

class Btn extends React.Component { 
  showBtn() {
    console.log(this);
  }
  render() {
    return <button onClick={() => this.showBtn()}>點(diǎn)擊</button>;
  }
}

結(jié)果如下:

  handleClick(e) { 
    console.log(this.ref1.current.showBtn === this.ref2.current.showBtn); // true
  }

說明: 事件綁定時(shí)的匿名函數(shù)+箭頭函數(shù) 靠譜!


結(jié)論, 就推薦以下2種寫法就行了:

1. 事件綁定時(shí)的 bind

class Btn extends React.Component {
  showBtn() {
    console.log(this);
  }
  render() {
    return <button onClick={this.showBtn.bind(this)}>點(diǎn)擊</button>;
  }
}

2. 事件綁定時(shí)的匿名函數(shù)+箭頭函數(shù)

class Btn extends React.Component {
  showBtn() {
    console.log(this);
  }
  render() {
    return <button onClick={() => this.showBtn()}>點(diǎn)擊</button>;
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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