为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

陪伴而非守候 2019-05-30 17:05:11
无法访问事件处理程序中的反应性实例(此)我正在用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
查看完整描述

3 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

this.changeContent需要通过this.changeContent.bind(this)作为onChange道具,否则this函数主体中的变量将不引用组件实例,而是引用window。看见功能:绑定.

使用时React.createClass而不是ES6类,定义在组件上的每个非生命周期方法都会自动绑定到组件实例。看见自动绑定.

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

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

VS

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

参考文献是在组件实例上设置的,而不是在React.refs:你需要改变React.refs.somerefthis.refs.someref。您还需要绑定sendContent方法到组件实例,以便this提到它。


查看完整回答
反对 回复 2019-05-30
?
狐的传说

TA贡献1804条经验 获得超3个赞

这个问题是我们大多数人在从React.createClass()扩展ES6类的组件定义语法React.Component.

它是由this背景差异React.createClass()VSextends React.Component.

使用React.createClass()将自动绑定this上下文(值)正确,但在使用ES6类时并非如此。当使用ES6方式时(通过扩展React.Component)this上下文是null默认情况下。类的属性不会自动绑定到Reaction类(组件)实例。


解决这一问题的途径

我一共知道4种一般的方法。

  1. 将函数绑定到类构造函数中。许多人认为这是一种最佳实践方法,它完全避免触及JSX,并且不会为每个组件重新呈现创建一个新功能。

    class SomeClass extends React.Component {
      constructor(props) {
        super(props);
        this.handleClick = this.handleClick.bind(this);
      }
      handleClick() {
        console.log(this); // the React Component instance
      }
      render() {
        return (
          <button onClick={this.handleClick}></button>
        );
      }}
  2. 将函数内联绑定。您仍然可以在一些教程/文章/等等中发现这种方法,因此您必须了解它。它的概念与#1相同,但要注意的是,绑定函数在每次重呈现时都会创建一个新函数。

    class SomeClass extends React.Component {
      handleClick() {
        console.log(this); // the React Component instance
      }
      render() {
        return (
          <button onClick={this.handleClick.bind(this)}></button>
        );
      }}
  3. 使用胖箭头函数。直到箭头函数,每个新函数都定义了自己的函数。this价值。但是,箭头函数不创建自己的this上下文,所以this具有来自Reaction组件实例的原始含义。因此,我们可以:

    class SomeClass extends React.Component {
      handleClick() {
        console.log(this); // the React Component instance
      }
      render() {
        return (
          <button onClick={ () => this.handleClick() }></button>
        );
      }}

    class SomeClass extends React.Component {
      handleClick = () => {
        console.log(this); // the React Component instance
      }
      render() {
        return (
          <button onClick={this.handleClick}></button>
        );
      }}
  4. 使用实用程序函数库自动绑定函数。有一些实用程序库可以自动为您完成任务。以下是一些流行的,仅举几个例子:

    • 自动装配器是将类的方法绑定到this,即使在分离方法时也是如此。包裹使用@autobind在绑定方法之前this指向正确的引用组件的上下文。

      import autobind from 'autobind-decorator';class SomeClass extends React.Component {
        @autobind
        handleClick() {
          console.log(this); // the React Component instance
        }
        render() {
          return (
            <button onClick={this.handleClick}></button>
          );
        }}

      AutoBindDecorator非常聪明,可以让我们一次绑定组件类中的所有方法,就像方法1一样。

    • 类自动绑定是另一个广泛用于解决此绑定问题的NPM包。与AutoBindDecorator不同,它不使用装饰器模式,而是真正使用只需在构造函数中使用一个自动绑定的函数。组件的方法以正确引用this.

      import autobind from 'class-autobind';class SomeClass extends React.Component {
        constructor() {
          autobind(this);
          // or if you want to bind only only select functions:
          // autobind(this, 'handleClick');
        }
        handleClick() {
          console.log(this); // the React Component instance
        }
        render() {
          return (
            <button onClick={this.handleClick}></button>
          );
        }}

      PS:其他非常类似的图书馆是反应自绑定.


建议

如果我是你,我会坚持第一种方法。但是,一旦您在类构造函数中获得了大量的绑定,我将建议您探索方法4中提到的一个助手库。


其他

这与你所面临的问题无关,但你不应过度使用参考文献.

你的第一个倾向可能是在你的应用程序中使用参考文献来“让事情发生”。如果是这样的话,花点时间更仔细地考虑一下在组件层次结构中应该在哪里拥有状态。

为了类似的目的,就像您需要的一样,使用受控元件是首选的方法。我建议你考虑用你的元件state。因此,您可以简单地访问如下所示的值:this.state.inputContent.


查看完整回答
反对 回复 2019-05-30
  • 3 回答
  • 0 关注
  • 688 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信