![](/img/trans.png)
[英]React Hooks: State is resetting to empty array even if I use the spread operator, prevState, etc
[英]What is the reason I have to use spread operator in React hooks?
预期行为
每次点击渲染计数器增加一
实际行为
渲染计数器不会增加,但内部会增加(如警报消息所示)。 看看这个截图: http : //prntscr.com/ujtsu9 (它不会一直发生..)
代码
import React, { Component, useState } from "react";
import "./App.css";
function App(props) {
const [all, setAll] = useState([{ name: "PHP", votes: 1 }]);
function changeAll() {
const newAll = all;
alert(newAll === all); //alert true
newAll[0].votes++;
setAll(newAll);
alert(all[0].votes);
}
return (
<>
<div className="voteCount">{all[0].votes}</div>
<div className="lanugageName">{all[0].name}</div>
<button onClick={changeAll}>Click Here</button>
</>
);
}
export default App;
我尝试过的:
更改行const newAll = all;
-> 到 -> const newAll = [...all];
然后它起作用了。 但是,然后警报说“假”
题
newAll === all
false ?为什么我需要使用扩展运算符?
您不需要使用扩展语法*,但您确实需要将要变异的现有状态浅复制为新的对象/数组/内存引用。 使用扩展语法是实现此目的的方法之一。 使用数组时,使用许多返回新数组的数组函数也很常见,例如 map、filter、slice。
如果我使用扩展运算符 [语法*],为什么
newAll === all
false ?
当您const newAll = all
您也将all
状态的引用保存到newAll
中,但是您const newAll = [...all]
您首先将状态传播到一个新的数组引用中,然后将其保存到newAll
试试看
const all = [1,2,3]; const newAll1 = all; const newAll2 = [...all]; console.log(newAll1 === all); // true console.log(newAll2 === all); // false
* 传播语法
我还想提醒你不要像这样的模式
newAll[0].votes++;
setAll(newAll);
即使您浅层复制了all
, newAll[0].votes++
仍会被视为状态突变。 如果您需要更新处于反应状态的数组元素,那么您还应该浅复制您打算更新的任何对象的属性。
setAll(all.map((el, index) => !index ? el : { ...el, votes: el.votes + 1 }))
更重要的是,如果任何状态更新取决于现有状态(增加计数是默认示例,顺便说一句),您将希望使用功能更新。
setAll(all => all.map((el, index) => !index ? el : { ...el, votes: el.votes + 1 }))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.