You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中.then()函数未等待state更新的原因及解决方案

React State 更新后异步回调无法获取最新值的问题解析

问题场景

在React项目中调用异步API获取数据后更新state,后续.then()回调里执行依赖该state的sortArray函数时,始终无法获取到更新后的foods state。

原代码示例

const [foods, setFoods] = useState([]);

api
  .getFood('fruits')
  .then((res) => {
    setFoods(res);
  })
  .then(() => sortArray(foods));

解决方案

最终通过useEffect监听状态结合useCallback解决了问题,代码如下:

const [foods, setFoods] = useState([]);
const [needsSorting, setNeedsSorting] = useState(false);

api
  .getFood('fruits')
  .then((res) => {
    setFoods(res);
  })
  .then(() => setNeedsSorting(true));

// 触发排序函数
useEffect(() => {
  if (needsSorting) {
    setNeedsSorting(false);
    sortArray();
  }
}, [needsSorting, sortArray]);

const sortArray = useCallback(() => {
  // 对foods数组进行排序的逻辑
}, [foods]);

原因解析

原方案无效的核心原因

  1. setState的异步特性:React的setState是异步批量更新机制,调用setFoods(res)后,React不会立刻修改foods的实际值,而是将更新任务加入队列,等待当前渲染周期结束后再统一处理。
  2. 闭包捕获旧值:第二个.then()回调里的foods是当前函数组件渲染周期的闭包变量,也就是初始的空数组。此时setFoods的更新还未完成,所以传给sortArray的始终是旧的state值。

新方案有效的原因

  1. useEffect确保执行时机:useEffect会在组件完成渲染、state更新完成后触发。当setNeedsSorting(true)执行后,组件会重新渲染,此时foods已经是API返回的最新数据,useEffect内调用sortArray自然能获取到最新state。
  2. useCallback稳定函数引用:sortArray用useCallback包裹后,只有当依赖项foods更新时,函数才会重新生成。这既保证了sortArray能捕获到最新的foods值,也让useEffect的依赖数组保持稳定,避免不必要的重复执行。

内容的提问来源于stack exchange,提问作者Cjmaret

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:01:02