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

Posted

技术标签:

【中文标题】从 for 循环中的多个连续异步调用中调用多个“setState”挂钩【英文标题】:Call multiple `setState` hooks from multiple successive async calls in a for loop 【发布时间】:2021-05-13 20:19:39 【问题描述】:

我有以下功能性 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 仅具有多个回调的一个任意结果。我怎样才能做到这一点?

【问题讨论】:

你能明确解释你想要达到什么结果吗?我不太明白你的意思 好吧,我在 for 循环中进行了多个 API 调用,我希望将所有结果存储在我的 dict 中,但正如我在问题中所说,React 似乎抑制了多个setDict 【参考方案1】:

问题

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

解决方案

使用功能状态更新。这里的区别在于功能状态更新是从前一个状态更新,而不是前一个渲染周期的状态。它只需要从setDict(...dict, [x]: res.y)setDict(dict =&gt; (...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));
        )
    );
  

【讨论】:

@7ball 太棒了!如果回答和解释有帮助,请不要忘记也请点赞。干杯。【参考方案2】:

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

【讨论】:

以上是关于从 for 循环中的多个连续异步调用中调用多个“setState”挂钩的主要内容,如果未能解决你的问题,请参考以下文章

vue js 2 - 多个rest调用中的for循环fetchData

如何在多个异步调用中向 NodeJS 中的数据库发送响应?

Node.js/Mongoose 等待异步 For 循环

如何更改 - 使用 for 循环调用多个函数 - 使用管道调用类?

使用R连续运行多个批处理文件?

如何等待来自 forEach 循环的多个异步调用?