无法访问事件处理程序中的 React 实例 (this)

2022-08-30 00:44:45

我正在用ES6(使用BabelJS)编写一个简单的组件,函数不起作用。this.setState

典型的错误包括

无法读取未定义的属性“setState”

this.setState 不是一个函数

你知道为什么吗?代码如下:

import React from 'react'

class SomeClass extends React.Component {
  constructor(props) {
    super(props)
    this.state = {inputContent: 'startValue'}
  }

  sendContent(e) {
    console.log('sending input content '+React.findDOMNode(React.refs.someref).value)
  }

  changeContent(e) {
    this.setState({inputContent: e.target.value})
  } 

  render() {
    return (
      <div>
        <h4>The input form is here:</h4>
        Title: 
        <input type="text" ref="someref" value={this.inputContent} 
          onChange={this.changeContent} /> 
        <button onClick={this.sendContent}>Submit</button>
      </div>
    )
  }
}

export default SomeClass

答案 1

this.changeContent在作为 prop 传递之前,需要通过绑定到组件实例,否则函数体中的变量将不会引用组件实例,而是引用 。请参阅函数::绑定this.changeContent.bind(this)onChangethiswindow

当使用 ES6 类代替 ES6 类时,在组件上定义的每个非生命周期方法都将自动绑定到组件实例。请参见自动绑定React.createClass

请注意,绑定函数会创建一个新函数。您可以直接在 render 中绑定它,这意味着每次组件呈现时都会创建一个新函数,也可以在构造函数中绑定它,该构造函数只会触发一次。

constructor() {
  this.changeContent = this.changeContent.bind(this);
}

render() {
  return <input onChange={this.changeContent.bind(this)} />;
}

Refs 是在组件实例上设置的,而不是在 : 您需要更改为 。您还需要将方法绑定到组件实例,以便该组件实例引用它。React.refsReact.refs.somerefthis.refs.somerefsendContentthis


答案 2

Morhaus是正确的,但这可以在没有的情况下解决。bind

您可以将箭头函数类属性建议一起使用

class SomeClass extends React.Component {
  changeContent = (e) => {
    this.setState({inputContent: e.target.value})
  } 

  render() {
    return <input type="text" onChange={this.changeContent} />;
  }
}

因为 arrow 函数是在构造函数的作用域中声明的,并且因为箭头函数从其声明作用域进行维护,所以它都可以正常工作。这里的缺点是这些不是原型上的函数,它们都将与每个组件一起重新创建。但是,这并不是一个很大的缺点,因为结果相同。thisbind