为什么在这个例子中不需要绑定

为什么在这个例子中不需要绑定

)}}

一些谷歌搜索表明我必须将它绑定到增量函数.但是为什么在我看到的第一个示例中不需要这样做?我将代码复制到 CodePen,它在 React 15.3.1 中运行良好,我在该示例中找不到任何类似于绑定的内容.只有在我在构造函数中添加绑定代码后,我的示例才开始工作.

class Counter 扩展 React.Component {构造函数(道具){超级(道具);this.state = {count: 0};//这一行解决了问题this.increment = this.increment.bind(this);}增量(上一个状态){this.setState((prevState) => ({计数:prevState.count + 1}));}使成为() {返回 (<div className="main"><button onClick={this.increment}>{this.state.count}</button>

)}}

解决方案

回答你的问题:第一个例子使用箭头函数,自动执行上下文绑定.来自文档:

箭头函数不会创建自己的 this 上下文,因此它具有它的原始含义来自封闭上下文.

React 中确实有一些绑定方式:

1) 你可以绑定 构造函数中的所有函数,就像你说的:

构造函数(道具){/* ... */this.increment = this.increment.bind(this);}

2) 使用箭头函数调用回调:

this.increment(e)}>

3) 附加 .bind 每次将其设置为回调时,都在方法引用的末尾,如下所示:

4) 在你的类中,定义带有箭头函数的方法:

increment = (e) =>{/* 你的类函数定义为 ES6 箭头函数 */}/* ... */<button onClick={this.increment}>

为了在 babel 中使用这个语法,你必须启用这个 plugin 或使用 stage-2 预设.

Trying to figure out the basics of React.

Looking at the second example on this page: https://facebook.github.io/react/I see that the tick() function sets the state of the Timer class, incrementing the previous value by one.

class Timer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
    );
  }
}

ReactDOM.render(<Timer />, mountNode);

However, when I tried to implement my own simple Counter class, it failed and I got a console error saying Cannot read property setState of undefined.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {count: 0};
    }

    increment(prevState) {
        this.setState((prevState) => ({
            count: prevState.count + 1
        }));
    }

  render() {
    return (
            <div className="main">
                <button onClick={this.increment}>{this.state.count}</button>
            </div>
    )
  }
}

Some Googling reveals that I have to bind this to the increment function. But why was that not required in the first example that I saw? I copied the code to CodePen and it ran fine with React 15.3.1 I cannot find anything resembling binding in that example. Only after I added binding code in the constructor did things start working in my example.

class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = {count: 0};

        // THIS ONE LINE FIXED THE ISSUE
        this.increment = this.increment.bind(this);
    }

    increment(prevState) {
        this.setState((prevState) => ({
      count: prevState.count + 1
    }));
    }

  render() {
    return (
            <div className="main">
                <button onClick={this.increment}>{this.state.count}</button>
            </div>
    )
  }
}
解决方案

Answering your question: the first example uses arrow functions, that automatically performs context binding. From the docs:

Indeed there are some ways of binding in React:

1) you can bind all functions in your constructor, like you said:

constructor(props) {
    /* ... */
    this.increment = this.increment.bind(this);
}

2) invoke your callbacks with arrow functions:

<button onClick={(e) => this.increment(e)}>

3) append .bind at the end of your method reference each time you set it as a callback, like this:

<button onClick={this.increment.bind(this)}>

4) In your class, define the method with arrow functions:

increment = (e) => {
  /* your class function defined as ES6 arrow function */
}

/* ... */

<button onClick={this.increment}>

In order to use this syntax with babel, you have to enable this plugin or use stage-2 preset.

这篇关于React - 为什么在这个例子中不需要绑定 this?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-24 07:31