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

React Native异步调用后状态更新数据错误问题排查

问题定位与解决方案

核心问题:竞态条件 + 未取消异步请求

快速切换标签页时,多次触发useFocusEffect会启动多个并行的异步请求。如果前一次页面失去焦点后,未完成的请求没有被取消,当它最终返回结果时,会覆盖当前页面的状态。若旧请求的响应晚于新请求,就可能出现tipPostList被错误赋值的情况。

解决步骤

1. 添加请求取消机制(推荐)

使用AbortController(axios v0.22.0+ 推荐)或CancelToken(已废弃),在页面失去焦点时取消未完成的请求,避免旧请求覆盖新状态。

修改CommunityPage.jsx:

const [tipPostList, setTipPostList] = useState([]);
const [freePostList, setFreePostList] = useState([]);

useFocusEffect(
  useCallback(() => {
    const controller = new AbortController();
    const fetchPosts = async () => {
      try {
        const [responseTip, responseFree] = await Promise.all([
          getPostsByType("TIP", controller.signal),
          getPostsByType("FREE", controller.signal),
        ]);
        setTipPostList(responseTip.data.slice(0, 3));
        setFreePostList(responseFree.data.slice(0, 3));
      } catch (error) {
        // 忽略请求取消的错误
        if (error.name !== "AbortError") {
          Sentry.captureException(error);
        }
      }
    };

    fetchPosts();

    // 页面失去焦点时取消请求
    return () => controller.abort();
  }, []),
);

修改api.js:

export const getPostsByType = (type, signal) => {
  return api.get("/posts", {
    params: { type },
    signal: signal
  });
};

2. 排查axios缓存配置

如果你的axios实例配置了缓存(如axios-cache-adapter),需确保缓存Key包含type参数。若缓存逻辑仅依据URL生成Key,会导致TIP和FREE请求共用同一缓存结果,引发状态赋值错误。

3. 验证请求返回数据

在前端添加日志,确认请求返回的responseTip和responseFree是否对应正确的类型,彻底排除后端返回数据的问题:

const [responseTip, responseFree] = await Promise.all([
  getPostsByType("TIP", controller.signal).then(res => {
    console.log("TIP请求返回:", res.data);
    return res;
  }),
  getPostsByType("FREE", controller.signal).then(res => {
    console.log("FREE请求返回:", res.data);
    return res;
  }),
]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:37:18