【问题标题】:React useState hook - update state of a objectReact useState hook - 更新对象的状态
【发布时间】:2021-01-01 10:26:22
【问题描述】:

我有一个清单对象状态

const [checkList, setCheckList] = useState({checkA, checkB .. 100 checks})

如何一次将所有状态更新为e.target.checked?我应该可以这样更新:

const handleAllCheck = (e) => {
Object.keys(checkList).map((resource) => {
  setCheckList({ ...checkList, [resource]: e.target.checked });
});

};

但这仅更新 100 项检查中的一项,我错过了什么?

【问题讨论】:

  • 是否要将所有checkX 值更新为e.target.checked 值?
  • @DrewReese 是的,所有checkXe.target.checked

标签: reactjs


【解决方案1】:

问题

您在一个循环中将一堆状态更新排入队列,但未使用功能状态更新,因此每次更新都使用与当前渲染周期中的更新排入队列相同的状态,从而覆盖先前的更新。最后入队的更新获胜,并且是为下一个渲染周期设置的状态。

const handleAllCheck = (e) => {
  Object.keys(checkList).map((resource) => {
    setCheckList({
      ...checkList, // <-- state from the previous render cycle
      [resource]: e.target.checked,
    });
  });
};

解决方案

为了更新所有检查的值,您可以简单地对键进行 forEach 并使用功能状态更新来传播上一次排队更新的状态。

const handleAllCheck = (e) => {
  const { checked } = e.target;
  Object.keys(checkList).forEach((resource) => {
    setCheckList(checkList => ({
      ...checkList, // <-- state from the previous update
      [resource]: checked,
    }));
  });
};

或者,您可以通过将旧状态减少为新状态对象来使用单个更新。

const handleAllCheck = (e) => {
  const { checked } = e.target;
  setCheckList(checkList => Object.keys(checkList).reduce(
    (checkList, resource) => ({
      ...checkList,
      [resource]: checked,
    }),
    {},
  ));
};

【讨论】:

    【解决方案2】:

    你可以试试

    const handleAllCheck = (e) => {
    const newCheckList = Object.keys(checkList).map((resource) => {
      return e.target.checked;
    });
    setCheckList(newCheckList);
    

    【讨论】:

    • 状态是一个对象,这会改变状态类型。如果这样做,那么您应该使用 array.prototype.reduce 回到对象中。
    猜你喜欢
    • 2021-11-13
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-22
    • 2021-09-09
    相关资源
    最近更新 更多