Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/466.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当直接改变状态时,为什么React会更新?_Javascript_Reactjs_Setstate - Fatal编程技术网

Javascript 当直接改变状态时,为什么React会更新?

Javascript 当直接改变状态时,为什么React会更新?,javascript,reactjs,setstate,Javascript,Reactjs,Setstate,在下面的示例中,我使用ES6映射作为React中的状态值: 类应用程序扩展了React.Component{ 建造师(道具){ 超级(道具); const results=新映射(); 结果[“group1”]=[{value:“…”},{value:“…”}]; this.state={results}; } onUpdate点击(i){ this.state.results[“group1”][i].value=i; this.setState({}); } 点击(i){ this.sta

在下面的示例中,我使用ES6映射作为React中的状态值:

类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
const results=新映射();
结果[“group1”]=[{value:“…”},{value:“…”}];
this.state={results};
}
onUpdate点击(i){
this.state.results[“group1”][i].value=i;
this.setState({});
}
点击(i){
this.state.results[“group1”][i].value=“…”;
this.setState({});
}
render(){
const{results}=this.state;
返回(
{results[“group1”].map((r,i)=>(
{r.value}
this.onUpdate单击(i)}>update
单击(i)}>reset
))}
);
}
}
render(,document.getElementById(“容器”)

你错了:

this.setState({}); // this will do nothing.
您希望状态应该用空对象更新。但事实并非如此

当您使用setState方法时,它希望属性更新。但是,由于您没有向setState提供任何属性,因此它将不起任何作用。但它仍然会根据setState性质重新渲染组件

更新:您的查询

编辑:我还想指出(因为许多答案都提到我传递的是一个空对象),如果我这样调用setState,组件将被重新渲染(和更新):

这似乎不应该导致重新渲染

React内部声明,当您尝试使用完全相同的状态更新状态时,它类似于
this.state.results
。所以,没有什么需要重新渲染的。但是,当对空对象使用setState时,React将闪烁其状态,以便进行重新渲染

请从以下位置阅读本说明:

注意

避免复制道具到状态!这是一个常见的错误:

constructor(props) {
 super(props);
 // Don't do this!
 this.state = { color: props.color };
}
问题是它既不必要(您可以直接使用
this.props.color
),又会产生错误(对颜色道具的更新不会反映在状态中)。

来自文档:

除非shouldComponentUpdate()返回false,否则setState()将始终导致重新渲染


这意味着
this.setState({})会导致重新渲染,无论您是否将更改作为参数传递

当调用
this.setState
时,它都会将传递给此函数的参数与旧的
this.state
合并以生成新的状态值。例如:

this.state = Object.assign({}, this.state, passedParam);

在上面的代码片段中,每次调用
this.setState({})已创建一个新的状态对象,该对象使组件重新呈现。

根据文档,除非shouldComponentUpdate()返回false,否则设置状态()将始终导致重新呈现。 您可以将render()函数视为创建React元素树。在下一次状态或道具更新时,render()函数将返回不同的React元素树(虚拟DOM

在任何时间点,React库都会维护虚拟DOM的两个副本

触发对setState()的请求时,React将创建一个新的树,其中包含组件中的反应元素(以及更新状态的)。 此树用于通过将组件的UI与前一个树的元素进行比较,确定组件的UI应如何响应状态更改

然后通过称为协调的过程与真实DOM同步的虚拟DOM

对于突变,不进行直接突变将避免项目中不必要的错误,因为setState()是异步的,这意味着您不能期望setState立即更新状态(它会成批更新),因此任何先前的突变都可能被先前的setState状态更新操作覆盖

裁判-

  • 反应文档

您调用的不是没有参数的
setState
,而是给它一个空对象。React随后将尝试更新,但由于空对象不包含任何要与前一状态合并的键,因此将保留您的变异。谢谢@Brianthonpson。我还要注意的是:setState({results:this.state.results})也会导致重新渲染,在这种情况下,我会再次问这个问题…作为参考:我不希望它被更新为空对象-如上所述,我希望没有任何更新,因为没有什么可比较的。啊,明白了。但如上所述,无论何时使用setState,react组件都将重新呈现,而不管其更改如何。
this.state = Object.assign({}, this.state, passedParam);