我知道,为尚未安装的组件设置状态时会引发错误。这就解释了我使用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,它知道这是第一次使用它吗?我可能把它简化得太多了,但如果有人有一个很好的技术答案作为原因,为什么不呢?
React类总是使用名为state
的属性初始化,该属性的值设置为null
,如源代码中所示。如您所知,React提供了一个setState
方法来操作此属性。根据文件:
setState()不会立即对此进行变异。状态,但创建挂起的状态转换。访问这个。调用此方法后的状态可能返回现有值。
无法保证对setState调用的同步操作,并且可能会对调用进行批处理以提高性能。
除非在shouldComponentUpdate()中实现了条件呈现逻辑,否则setState()将始终触发重新呈现。
简而言之,setState()是一个异步的、多步骤的、不可预测的操作,它会导致组件重新呈现。调用这样的函数需要对象已经完全初始化,因此在类仍在安装时不可能发生。在完全初始化之前,它已经尝试对类执行生命周期操作。
当然,如果您希望组件以非null
的状态开始,但又不希望立即导致多个渲染和操作发生,那么这就留下了一个问题。这就是为什么React提供了一种不依赖setState
初始化组件状态的方法。在ES5中,这是在名为getInitialState
的属性内设置初始状态。然而,ES6引入了本机语法,用于在使用特殊构造函数方法初始化类时设置属性(因此React不再需要自己的自定义版本)。这就是为什么,如果要在安装时用状态初始化React组件,必须将其声明为this。state={}
并且不使用setState()
。