猿问

无法访问事件处理程序中的反应性实例(此)

无法访问事件处理程序中的反应性实例(此)

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

典型的错误包括

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

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


陪伴而非守候
浏览 689回答 3
3回答

潇湘沐

this.changeContent需要通过this.changeContent.bind(this)作为onChange道具,否则this函数主体中的变量将不引用组件实例,而是引用window。看见功能:绑定.使用时React.createClass而不是ES6类,定义在组件上的每个非生命周期方法都会自动绑定到组件实例。看见自动绑定.请注意,绑定函数会创建一个新函数。您可以直接在呈现中绑定它,这意味着每次组件呈现时都会创建一个新函数,或者在构造函数中绑定它,而构造函数只会触发一次。constructor()&nbsp;{ &nbsp;&nbsp;this.changeContent&nbsp;=&nbsp;this.changeContent.bind(this);}VSrender()&nbsp;{ &nbsp;&nbsp;return&nbsp;<input&nbsp;onChange={this.changeContent.bind(this)}&nbsp;/>;}参考文献是在组件实例上设置的,而不是在React.refs:你需要改变React.refs.someref到this.refs.someref。您还需要绑定sendContent方法到组件实例,以便this提到它。

狐的传说

这个问题是我们大多数人在从React.createClass()扩展ES6类的组件定义语法React.Component.它是由this背景差异React.createClass()VSextends React.Component.使用React.createClass()将自动绑定this上下文(值)正确,但在使用ES6类时并非如此。当使用ES6方式时(通过扩展React.Component)this上下文是null默认情况下。类的属性不会自动绑定到Reaction类(组件)实例。解决这一问题的途径我一共知道4种一般的方法。将函数绑定到类构造函数中。许多人认为这是一种最佳实践方法,它完全避免触及JSX,并且不会为每个组件重新呈现创建一个新功能。class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;constructor(props)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;super(props); &nbsp;&nbsp;&nbsp;&nbsp;this.handleClick&nbsp;=&nbsp;this.handleClick.bind(this); &nbsp;&nbsp;} &nbsp;&nbsp;handleClick()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={this.handleClick}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}将函数内联绑定。您仍然可以在一些教程/文章/等等中发现这种方法,因此您必须了解它。它的概念与#1相同,但要注意的是,绑定函数在每次重呈现时都会创建一个新函数。class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;handleClick()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={this.handleClick.bind(this)}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}使用胖箭头函数。直到箭头函数,每个新函数都定义了自己的函数。this价值。但是,箭头函数不创建自己的this上下文,所以this具有来自Reaction组件实例的原始含义。因此,我们可以:class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;handleClick()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={&nbsp;()&nbsp;=>&nbsp;this.handleClick()&nbsp;}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}或class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;handleClick&nbsp;=&nbsp;()&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={this.handleClick}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}使用实用程序函数库自动绑定函数。有一些实用程序库可以自动为您完成任务。以下是一些流行的,仅举几个例子:自动装配器是将类的方法绑定到this,即使在分离方法时也是如此。包裹使用@autobind在绑定方法之前this指向正确的引用组件的上下文。import&nbsp;autobind&nbsp;from&nbsp;'autobind-decorator';class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;@autobind &nbsp;&nbsp;handleClick()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={this.handleClick}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}AutoBindDecorator非常聪明,可以让我们一次绑定组件类中的所有方法,就像方法1一样。类自动绑定是另一个广泛用于解决此绑定问题的NPM包。与AutoBindDecorator不同,它不使用装饰器模式,而是真正使用只需在构造函数中使用一个自动绑定的函数。组件的方法以正确引用this.import&nbsp;autobind&nbsp;from&nbsp;'class-autobind';class&nbsp;SomeClass&nbsp;extends&nbsp;React.Component&nbsp;{ &nbsp;&nbsp;constructor()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;autobind(this); &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;or&nbsp;if&nbsp;you&nbsp;want&nbsp;to&nbsp;bind&nbsp;only&nbsp;only&nbsp;select&nbsp;functions: &nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;autobind(this,&nbsp;'handleClick'); &nbsp;&nbsp;} &nbsp;&nbsp;handleClick()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;console.log(this);&nbsp;//&nbsp;the&nbsp;React&nbsp;Component&nbsp;instance &nbsp;&nbsp;} &nbsp;&nbsp;render()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<button&nbsp;onClick={this.handleClick}></button> &nbsp;&nbsp;&nbsp;&nbsp;); &nbsp;&nbsp;}}PS:其他非常类似的图书馆是反应自绑定.建议如果我是你,我会坚持第一种方法。但是,一旦您在类构造函数中获得了大量的绑定,我将建议您探索方法4中提到的一个助手库。其他这与你所面临的问题无关,但你不应过度使用参考文献.你的第一个倾向可能是在你的应用程序中使用参考文献来“让事情发生”。如果是这样的话,花点时间更仔细地考虑一下在组件层次结构中应该在哪里拥有状态。为了类似的目的,就像您需要的一样,使用受控元件是首选的方法。我建议你考虑用你的元件state。因此,您可以简单地访问如下所示的值:this.state.inputContent.
随时随地看视频慕课网APP
我要回答