【问题标题】:React: Error referencing a function within state反应:在状态中引用函数时出错
【发布时间】:2020-06-05 18:49:15
【问题描述】:

这个问题看起来很简单,但我不知道如何解决它:

  • render-Function 中声明的添加按钮可以正常工作
  • state 中声明的添加按钮本身不起作用。正如代码已经提到的,它会抛出"TypeError: Cannot read property 'state' of undefined"-Error
class App extends Component {
  constructor() {
    super();

    this.state = {
      someArrayOfObjects: [{
          attr: 
             // SNIP ...
                // Doesn't work!
                // When clicked leads to this error: "TypeError: Cannot read property 'state' of undefined"
                <button onClick={this.doAction}>Add</button>
             // SNIP ...
        }]
    };

    this.doAction = this.doAction.bind(this);
  }

  // SNIP ...
  doAction() {
    console.log(this.state);
  }

  render() {
      return(
          // SNIP...
          // Works just fine
          <button onClick={this.doAction}>Add</button>
      )
  }
}

我错过了什么?

【问题讨论】:

  • 尝试使用箭头函数&lt;button onClick={() =&gt; this.doAction}&gt;Add&lt;/button&gt;
  • 如果要绑定doAction,请在将其传递给状态声明中的组件之前执行此操作。否则,调用该函数时 this 将是未定义的。
  • @Sam 谢谢,但箭头功能不起作用

标签: javascript reactjs react-state-management


【解决方案1】:

你需要在state之前绑定函数doAction

constructor() {
    super();

    this.doAction = this.doAction.bind(this);

    this.state = {
      someArrayOfObjects: [{
          attr: 
             // SNIP ...
                // Doesn't work!
                // When clicked leads to this error: "TypeError: Cannot read property 'state' of undefined"
                <button onClick={this.doAction}>Add</button>
             // SNIP ...
        }]
    };

  }

编辑: 您需要在状态创建之前绑定函数。在您创建状态下的按钮时,this.doAction 指的是组件类的原型方法。但是你can't pass a method as a callback directly,所以需要绑定。 Function.prototype.bindcreates a new function,然后将其分配给在构造函数中创建的实例:

this.doAction = this.doAction.bind(this);

因此,可能令人困惑的是,this.doAction 在代码的不同点指代两个不同 函数。您想将绑定的版本传递给处理程序(请参阅上面的链接了解原因),因此您需要在创建该按钮之前对其进行绑定。

【讨论】:

  • 这是正确答案,但可以通过解释为什么来改进。
  • @JaredSmith 添加了一些解释,我认为这不是最好的:/ 我写得更好
  • 这是一个相当不错的第一关。我为您修改了它,如果您有任何问题,请告诉我,或者如果您认为某些内容可能更清楚,请随时自行进一步编辑。很好的答案。
  • @rMonteiro 感谢它就像一个魅力。想知道为什么我不尝试自己将线路移动到顶部。然而:我应该总是把它们放在首位吗?或者有什么缺点?
  • @trynalearn 我认为将绑定放在顶部没有任何缺点,但您只需要在这种情况下这样做。
【解决方案2】:

请检查沙箱中的代码: https://codesandbox.io/s/young-architecture-0r1tk

在这里你可以看到我们需要在添加到状态之前定义方法。 首先我们需要定义doAction 方法然后是状态,因为它是在状态内部使用的。

【讨论】:

  • 这应该是对 rmontiero 答案的修改,因为它本身并不能作为答案。
猜你喜欢
  • 2021-05-03
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 2017-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多