如何使用 useState 钩子在 forEach 循环中设置状态

IT技术 javascript reactjs react-hooks
2021-05-01 12:38:17

我想将数组 A 中的数据传输到对象 B,所以我做了类似 [array].forEach(e => setB({...B, e})) 的事情,但似乎在遍历后面的元素时,以前的行为已经“忘记”了,我该如何实现我的目标?
原型应该是这样的:

import React from "react"
import {Map} from "immutable"

export default function App() {
    const [arrayA, setA] = React.useState([1, 2]);
    const [objB, setB] = React.useState(Map({}));
    React.useEffect(() => {
        arrayA.forEach(num => {
            setB(objB.set(num, num*num));
        })
    }, [])

    return (<div>null</div>)
}

提前致谢!

2个回答

你是对的。通过循环中的常规值状态更新,每个后续入队更新都会覆盖前一次更新,因此最后一次更新是用于下一个渲染周期的更新。

解决方案

通常,您会使用功能状态更新来更新前一个状态,而不是前一个渲染周期的状态。在这种情况下,将arrayA状态映射到键值对数组并对该objB状态进行一次更新更有意义

React.useEffect(() => {
  setB(Map(arrayA.map(num => [num, num * num]));
}, []);

你得到了stale data,你应该setState callback像这样使用

export default function App() {
  const [arrayA, setA] = React.useState([1, 2]);
  const [objB, setB] = React.useState(Map({}));
  React.useEffect(() => {
    arrayA.forEach((num) => {
      setB(oldValue => oldValue.set(num, num * num));
    });
  }, []);

  return <div>null</div>;
}