提问者:小点点

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


我知道,为尚未安装的组件设置状态时会引发错误。这就解释了我使用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>
);
  }
}

取消注释第二行时出现的错误。setState({term:'})是:

警告:设置状态(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是禁止操作。请检查组件的代码。

我知道如何防止错误,只需显式地设置状态,而不告诉React任何关于它的信息,我已经看到github问题在谈论bug:github问题#3878但我想知道的是为什么不能React解决它?如果从构造函数调用setState,它知道这是第一次使用它吗?我可能把它简化得太多了,但如果有人有一个很好的技术答案作为原因,为什么不呢?


共1个答案

匿名用户

React类总是使用名为state的属性初始化,该属性的值设置为null,如源代码中所示。如您所知,React提供了一个setState方法来操作此属性。根据文件:

setState()不会立即对此进行变异。状态,但创建挂起的状态转换。访问这个。调用此方法后的状态可能返回现有值。

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

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

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

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