为什么在类构造函数中使用setState方法时React会抛出错误?

时间:2016-04-07 22:17:58

标签: javascript reactjs constructor state

我知道为尚未挂载的组件设置状态时会引发错误。这解释了我使用setState函数作为明确和直接设置状态的错误。

import React, {Component} from 'react';

class SearchBar extends Component {

constructor(props) {
  super(props);

  this.state = {term: ''}; // -> seems to be the agreed means to set   initial state
// this.setState({term: ''}); // -> generates an error
}

render() {
  return (
    <div>
      <input onChange={event => this.setState({term:   event.target.value})}/>
      Value of the input: {this.state.term}
  </div>
);
  }
}
  

我取消注释第二行this.setState({term:''})时得到的错误是:

警告:setState(...):只能更新已安装或安装的组件。这通常意味着您在已卸载的组件上调用了setState()。这是一个无操作。请检查组件的代码。

我知道如何防止错误,只需明确设置状态而不告诉React有关它的任何内容我已经看到github问题讨论了这个错误:Github Issue #3878我想知道的是为什么不能反应搞定了吗?如果从构造函数中调用setState,它知道这是第一次使用它吗?我可能太简单了,但如果有人有一个很好的技术答案,为什么不呢?

1 个答案:

答案 0 :(得分:10)

React类始终使用名为state的属性进行初始化,设置为null,如source code中所示。如您所知,React提供了一个setState方法来操作此属性。根据{{​​3}}:

  

setState()不会立即改变this.state,但会创建挂起状态转换。在调用此方法后访问this.state可能会返回现有值。

     

无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升。

     

除非在shouldComponentUpdate()中实现条件呈现逻辑,否则setState()将始终触发重新呈现。

简而言之,setState()是一个异步,多步骤,不可预测的操作,会导致组件重新出现。要调用这样的函数,需要一个对象已经完全初始化,因此在类仍在挂载时不会发生。在完全初始化之前,它已经尝试在类上执行生命周期操作。

当然,如果您希望组件以非null的状态开始但又不想立即导致多个渲染和操作,则会出现问题。这就是为什么React提供了一种在不依赖setState的情况下初始化组件状态的方法。在ES5中,这是在名为getInitialState的属性中设置初始状态。但是,当使用特殊的docs方法初始化类时,ES6引入了用于设置属性的本机语法(因此React不再需要自己的自定义版本)。这就是为什么,如果要在安装时使用状态初始化React组件,则必须将其声明为this.state = {}而不是setState()