React 事件处理程序中 this 的值

Value of this in React event handler

出于某种原因,this 的值在 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 对我来说是新手,但这似乎不是正确的行为?

如果您使用新的 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>
  }
}

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

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

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

接受的答案很好,我在 ES6 中经常使用它,但我只想添加另一个 "more modern" ES7 解决方案(在 React component class auto-binding notes): use arrow functions as class properties 中提到,然后你不需要在任何地方绑定或包装您的处理程序。

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

这是迄今为止最简单、最干净的解决方案!