从 for 循环中的多个连续异步调用调用多个 setState 挂钩

Call multiple `setState` hooks from multiple successive async calls in a for loop

我有以下功能性 React 组件:

const MyComp = (props) => {
  const [dict, setDict] = useState({});

  const myFunc = () => {
    [1, 2, 3].forEach(x => {
      fetch('something' + x)
        .then(res => res.json())
        .then(res => {
          setDict({...dict, [x]: res.y}); // <--------   PROBLEMATIC HERE
        })
    });
  }
}

似乎 React 正在对此进行预优化,所以我所有的 setDict 调用都被合并为一个。这意味着 dict 只有多个回调的一个任意结果。我怎样才能做到这一点?

问题

您正在使用标准更新在循环中对状态更新进行排队。这意味着每个更新都使用更新排队的渲染周期中的状态。每个后续更新都会覆盖先前的状态更新,因此最终结果是最后一个排队更新是为下一个渲染周期设置状态的更新。

解决方案

使用功能状态更新。这里的区别在于功能状态更新是从前一个状态更新的,而不是从前一个渲染周期更新的状态。它只需要从 setDict({...dict, [x]: res.y})setDict(dict => ({...dict, [x]: res.y})) 的小调整。

const MyComp = (props) => {
  const [dict, setDict] = useState({});

  const myFunc = () => {
    [1, 2, 3].forEach(x => {
      fetch('something' + x)
        .then(res => res.json())
        .then(res => {
          setDict(dict => ({...dict, [x]: res.y}));
        })
    });
  }
}

setState 在回调的第一个参数中提供您所在州的当前值

因此使用来自回调参数的 dict 值而不是 dict

的状态值
const MyComp = (props) => {
const [dict, setDict] = useState({});

const myFunc = () => {
  [1, 2, 3].forEach(x => {
    fetch('something' + x)
      .then(res => res.json())
      .then(res => {
        setDict((dict) => {...dict, [x]: res.y}); // <--------   PROBLEMATIC HERE
      })
  });
}