javascript - 使用 useState 更新深层嵌套状态无法正常工作
问题描述
我按照这个线程中的答案尝试更新我在 React 中深度嵌套的对象。 React:使用 Hooks 为深度嵌套对象设置状态
在那里看起来像魅力的东西,在执行以下操作时会以某种方式打破:
我有一个表,其中填充了来自如下定义的数组中的项目:
const [items, setItems] = useState([
{
selected: false,
title: 'Item 1',
status: 'new'
},
{
selected: false,
title: 'Item 2',
status: 'used'
},
]);
从该列表中选择一个项目时,调用此函数以更新selected
具有索引的对象的变量,i
如下所示:
const select = (e) => {
const i = e.target.getAttribute('data-index');
setItems((prevState) => {
prevState[i].selected = !prevState[i].selected;
return [...prevState];
});
};
这将只工作一次。如果我第二次触发select
或在此之后的任何时间以return [...prevState]
某种方式继续返回状态不变。(selected
永远true
存在)。我无法解决这个问题。
items
像这样附加到一个组件List
:
<List
items={items}
/>
和内部List
(缩短的代码):
{items.map((item, i) => {
return (
<tr className="list-table-tr">
{hasSelector ? (
<td className="list-table-td-selector">
{item.selected ? (
<div
data-index={i}
className="global-selector-selected"
onClick={select}
></div>
) : (
<div
data-index={i}
className="global-selector-unselected"
onClick={select}
></div>
)}
</td>
) : null}
解决方案
你打破了 React 状态的主要规则之一:你直接修改一个状态对象,而不是制作一个副本。
要正确进行更新,您可以这样做:
const select = (e) => {
const i = e.target.getAttribute('data-index');
setItems((prevState) => {
// Copy the array (your code was doing that)
const update = [...prevState];
const item = update[i];
// Copy the object (your code wasn't doing that) and update its
// `selected` property
update[i] = {...item, selected: !item.selected};
return update;
});
};
请注意如何复制数组和对象,而不仅仅是数组。
推荐阅读
- c# - SSIS C# 客户端发送 SOAP 请求和接收响应
- vb.net - 每个 .Net 项目有多少个 VB.net System.Timers.Timers?
- excel - 如何在工作表中搜索现有的命令按钮?
- constraints - 约束方法
- json - 在 API Post 方法中引用相关资源
- r - 我的公平骰子模拟不会输出 1 到 6 之间的 10 个随机数
- postgresql - 从 postgresql 中的两个值中查找 %
- php - SQLSTATE [23000]:完整性约束违规:1062 Symfony 4 中的重复条目
- elasticsearch - 如何通过弹性搜索中的特定值查找具有多个字段的内部对象的对象
- vb6 - 将范围参数传递给 Crystal 对象