React 事件处理程序中 this 的值

IT技术 reactjs react-jsx
2021-04-15 00:52:25

出于某种原因, this 的值在react事件处理程序中丢失了。阅读文档我认为 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个回答

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

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

所以你需要使用:

 <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>
  }
}
请注意,在您链接到的文档中,还提供了另一个使用 ES7 类属性创建箭头函数处理程序的解决方案, ex handleClick = (e) => { },然后bind在构造函数或任何地方都不需要调用。
2021-05-23 00:52:25
编辑了您的答案以阐明自动绑定在所有版本的 React 中继续与 React.createClass 一起使用。
2021-06-04 00:52:25
感谢本的澄清。
2021-06-17 00:52:25

接受的答案很好,我在 ES6 中使用了很多,但我只想添加另一个我们在 ES7 中拥有的“更现代”的解决方案(在React 组件类自动绑定注释中提到):使用箭头函数作为类properties,那么您不需要在任何地方绑定或包装您的处理程序。

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

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

不是onClick={e => this.handleClick(e)}更有效吗?我相信它几乎相同,this.handleClick = this.handleClick.bind(this)只是后者更多的是双重输入。
2021-05-23 00:52:25
我的示例不使用.bind(),它将粗箭头定义为类属性,并简单地将其传递到回调道具中。我认为这比在回调 prop 的每个渲染中定义箭头函数更有效,并且输入更少,特别是如果您想在渲染函数的多个位置使用处理程序。
2021-05-23 00:52:25

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

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

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

是的,需要onClick={e => this.handleClick(e.target)}handleClick 函数来获取被点击的元素。
2021-05-31 00:52:25
在您的箭头示例中,handleClick 方法不会将 DOM 元素作为参数获取,除非您明确传递它,对吗?
2021-06-16 00:52:25