学无先后,达者为师

网站首页 编程语言 正文

react:理解“为了在回调中使用 `this`,这个绑定是必不可少的”

作者:你吃香蕉吗? 更新时间: 2023-04-20 编程语言

一、官网代码

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = {isToggleOn: true};

    // 为了在回调中使用 `this`,这个绑定是必不可少的
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(state => ({
      isToggleOn: !state.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}

ReactDOM.render(
  <Toggle />,
  document.getElementById('root')
);

二、官网解释

你必须谨慎对待 JSX 回调函数中的 this,在 JavaScript 中,class 的方法默认不会绑定 this。如果你忘记绑定 this.handleClick 并把它传入了 onClick,当你调用这个函数的时候 this 的值为 undefined

这并不是 React 特有的行为;这其实与 JavaScript 函数工作原理有关。通常情况下,如果你没有在方法后面添加 (),例如 onClick={this.handleClick},你应该为这个方法绑定 this

三、ES6 class

class Example {
    constructor(a, b) {
        this.a = a;
        this.b = b;
        console.log('Example');
    }
    sum() {
        return this.a + this.b;
    }
}
let exam1 = new Example(2, 1);
let exam2 = new Example(3, 1);
console.log(exam1.sum()); // 3
console.log(exam2.sum()); // 4

以上代码可以看出es6中的class是不需要给方法单独绑定this的

四、ES6 class不需要单独绑定this,那为什么react中要单独绑定this?

关键的一句话:当函数作为回调函数被调用时

onClick={this.handleClick} 就是将handleClick作为回调函数使用的

改造一下第三点的代码,将exam1.sum和exam2.sum作为回调函数使用:

class Example {
    constructor(a, b) {
        this.a = a;
        this.b = b;
    }
    sum() {
        return this.a + this.b;
    }
}
let exam1 = new Example(2, 1);
let exam2 = new Example(3, 1);
function getSum(cb) {
    console.log('cb', cb());
}
getSum(exam1.sum)
getSum(exam2.sum)

此时代码执行报错:

Uncaught TypeError: Cannot read properties of undefined (reading 'a')

显然 this 此时是undefined

五、作为回调函数时正确的代码

class Example {
    constructor(a, b) {
        this.a = a;
        this.b = b;
        this.sum = this.sum.bind(this);
    }
    sum() {
        return this.a + this.b;
    }
}
let exam1 = new Example(2, 1);
let exam2 = new Example(3, 1);

function getSum(cb) {
    console.log('cb', cb());
}
getSum(exam1.sum)
getSum(exam2.sum)

原文链接:https://blog.csdn.net/m0_47135993/article/details/126174562

栏目分类
最近更新