React事件处理程序中的值

jam*_*day 19 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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

但这样做:

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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Wir*_*rie 31

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

自动绑定功能不适用于 v0.13.0中的ES6类.

所以你需要使用:

 <button onClick={this.handleClick.bind(this)}>Click</button>
Run Code Online (Sandbox Code Playgroud)

或者其他一个技巧:

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

  • 请注意,在您链接到的文档中,还提供了另一种使用 ES7 类属性创建箭头函数处理程序的解决方案,例如 `handleClick = (e) =&gt; { }`,然后在构造函数或任何地方都不需要 `bind` 调用。 (2认同)

Aar*_*all 15

接受的答案是好的,我在ES6中使用了很多,但我只想添加另一个与ES7相关的"更现代"的解决方案(在React组件类自动绑定说明中提到):使用箭头函数作为类属性,那么您不需要在任何地方绑定或包装您的处理程序.

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

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

  • 我的例子不使用`.bind()`,它将胖箭头定义为类属性,并简单地将它传递给回调道具.我认为这比在回调道具的每个渲染中定义箭头函数更有效,而且输入更少,特别是如果你想在渲染函数中的多个位置使用处理程序. (2认同)

And*_*ahl 10

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

代替: onClick={this.handleClick.bind(this)}

这是因为这意味着您可以在测试中使用间谍替换handleClick方法,这是使用bind时无法执行的操作.