React事件处理程序中的值

时间:2015-04-19 15:44:56

标签: reactjs react-jsx

由于某种原因,这个值在react事件处理程序中丢失了。阅读文档,我认为反应在这里做了一些事情,以确保将其设置为正确的值

以下并不像我期待的那样工作

import React from 'react';

export default class Observer extends React.Component {

    handleClick() {
        console.log(this); //logs undefined
    }
    render() {
        return (
            <button onClick={this.handleClick}>Click</button>
        );
    }
}

但这样做:

import React from 'react';

export default class Observer extends React.Component {

    handleClick() {
        console.log(this); //logs Observer class instance
    }
    render() {
        return (
            <button onClick={this.handleClick.bind(this)}>Click</button>
        );
    }
}

React和ES6对我来说是新手,但这似乎不是正确的行为?

3 个答案:

答案 0 :(得分:29)

如果您使用新的class语法,这是JavaScript和React的正确行为。

v0.13.0中的autobinding feature does not apply to ES6 classes

所以你需要使用:

 <button onClick={this.handleClick.bind(this)}>Click</button>

或其他一些技巧:

export default class Observer extends React.Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    /* ... */
  }
  render() {
      return <button onClick={this.handleClick}>Click</button>
  }
}

答案 1 :(得分:14)

接受的答案很好,我在ES6中经常使用它,但我只想添加另一个更现代的#34;我们使用ES7的解决方案(在React component class auto-binding notes中提到):使用箭头函数作为class properties,然后您不需要将处理程序绑定或包装在任何地方。

export default class Observer extends React.Component {
  handleClick = (e) => {
    /* ... */
  }
  render() {
      return <button onClick={this.handleClick}>Click</button>
  }
}

这是最简单,最干净的解决方案!

答案 2 :(得分:10)

就像其他人所说的那样,当使用ES6类时,React不会将方法自动绑定到实例。也就是说,我会习惯在事件处理程序中始终使用箭头函数,例如:onClick={e => this.handleClick()}

而不是:onClick={this.handleClick.bind(this)}

这是因为这意味着您可以在测试中用spy替换handleClick方法,这是使用bind时无法做到的。