简体   繁体   English

React 事件处理程序中 this 的值

[英]Value of this in React event handler

For some reason the value of this is being lost in react event handler.出于某种原因, this 的值在反应事件处理程序中丢失了。 Reading the docs I thought that react did some stuff here to make sure this was set to the correct value阅读文档我认为 react 在这里做了一些事情以确保将其设置为正确的值

The following doesn't work as I'd expect以下不符合我的预期

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>
        );
    }
}

But this does:但这确实:

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 and ES6 is new to me but this seems to not be the correct behaviour? React 和 ES6 对我来说是新手,但这似乎不是正确的行为?

This is correct behavior for JavaScript and React if you use the new class syntax.如果您使用新的class语法,这是 JavaScript 和 React 的正确行为。

The autobinding feature does not apply to ES6 classes in v0.13.0.自动绑定功能不适用于v0.13.0 中的ES6 类

So you'll need to use:所以你需要使用:

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

Or one of the other tricks:或其他技巧之一:

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

The accepted answer is good and I've used it a lot in ES6, but I just want to add another "more modern" solution we have with ES7 (mentioned in the React component class auto-binding notes ): use arrow functions asclass properties , then you don't need to bind or wrap your handler anywhere.接受的答案很好,我在 ES6 中使用了很多,但我只想添加另一个我们在 ES7 中拥有的“更现代”的解决方案(在React 组件类自动绑定注释中提到):使用箭头函数作为类properties ,那么您不需要在任何地方绑定或包装您的处理程序。

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

This is the simplest and cleanest solution yet!这是迄今为止最简单、最干净的解决方案!

Like others have said, React doesn't autobind methods to the instance when using ES6 classes.正如其他人所说,React 在使用 ES6 类时不会自动将方法绑定到实例。 That said, I would make habit of always using arrow functions in event handlers like: onClick={e => this.handleClick()}也就是说,我会养成在事件处理程序中始终使用箭头函数的习惯,例如: onClick={e => this.handleClick()}

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

This because it means that you can replace the handleClick method with a spy in a test, something you can't do when you use bind.这是因为这意味着您可以在测试中用 spy 替换 handleClick 方法,这是您在使用 bind 时无法做到的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM