使用 useState 更新深层嵌套状态无法正常工作

Updating deeply nested state with useState not working properly

我按照此线程中的答案尝试在 React 中更新我的深层嵌套对象。

那里似乎很有魅力的东西,在执行以下操作时会以某种方式破坏我:

我有一个 table 填充了如下定义的数组中的项目:

const [items, setItems] = useState([
{
  selected: false,
  title: 'Item 1',
  status: 'new'
},
{
  selected: false,
  title: 'Item 2',
  status: 'used'
},
]);

从该列表中选择一个项目时,将调用此函数来为索引为 i 的对象更新 selected 变量,如下所示:

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;
    });
};

注意如何数组对象被复制,而不仅仅是数组。