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

React Native中如何通过useEffect顺序执行异步API请求

问题核心原因

你现在的代码有两个典型问题导致顺序不生效:

  • 两个异步函数在useEffect里并列调用,没有等待前一个执行完成就会启动下一个,本身就存在竞态
  • 就算你给getUserToken()加await,React的state更新是异步批处理的,getUserId函数闭包里捕获的永远是组件初始化时的空userToken值,哪怕setUserToken已经触发,getUserId也拿不到最新值
  • 额外提一句:你写的AsyncStorage.getItem("userToken", userToken)传参错误,这个API只需要传入存储key作为第一个参数,第二个参数是多余的。
推荐实现方式

不要靠state在两个独立函数之间传递中间值,把强依赖的串行步骤放到同一个异步流程里执行,从根源上避开闭包陷阱,同时保证执行顺序,代码如下:

useEffect(() => {
  const initPageData = async () => {
    try {
      // 第一步:读取本地存储的token
      const storedToken = await AsyncStorage.getItem("userToken");
      if (!storedToken) {
        // 无token场景可在这里处理,比如跳登录页
        console.log("未检测到登录凭证");
        return;
      }
      // 如果页面其他逻辑需要用到token,再存到state
      setUserToken(storedToken);

      // 第二步:携带刚拿到的token请求用户信息
      const userRes = await xano.get("/auth/me", {
        headers: { Authorization: storedToken },
      });
      const uid = userRes.data.id;
      setUserId(uid);
      // 注意:setState是异步的,不要在setUserId之后立刻console.log(userId),直接打局部变量uid即可
      console.log("当前用户ID:", uid);
    } catch (err) {
      console.log("页面初始化数据加载失败", err);
      // 可在这里统一处理错误,比如token过期清空存储跳登录
    }
  };

  initPageData();
}, []);
方案说明
  • 所有初始化逻辑封装在同一个async函数内,通过await严格保证执行顺序:token读取完成前绝对不会发起用户信息请求
  • 请求用户信息时直接使用await拿到的局部变量storedToken,完全不依赖state更新,彻底解决闭包拿到旧值的问题
  • 增加了空token提前判断,避免发起无效的鉴权请求
  • 错误统一在流程内捕获,不需要在多个拆分函数里重复写错误处理逻辑,维护性更好
  • useEffect依赖数组为空,整个逻辑只会在组件首次挂载时执行一次,完全符合你的需求

如果你确实需要拆分两个函数做逻辑复用,记得让读取token的函数返回拿到的token值,请求用户信息的函数接收token作为入参,不要直接读取闭包内的state变量,调用时按顺序await即可,参考写法:

const getUserToken = async () => {
  try {
    const token = await AsyncStorage.getItem("userToken");
    setUserToken(token);
    return token;
  } catch (err) {
    console.log("读取token失败", err);
    return null;
  }
};

const getUserId = async (token) => {
  if (!token) return;
  try {
    const res = await xano.get("/auth/me", {
      headers: { Authorization: token },
    });
    setUserId(res.data.id);
  } catch (err) {
    console.log("获取用户信息失败", err);
  }
};

useEffect(() => {
  const runInit = async () => {
    const token = await getUserToken();
    await getUserId(token);
  };
  runInit();
}, []);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 22:45:43