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

React Native异步函数执行顺序异常:getDetails与setCurrentIndex未按预期执行

问题分析与解决方案

核心问题

  • React状态更新是异步操作,await getDetails()无法等待currDetails状态更新完成就执行setCurrentIndex(),导致后者使用的仍是旧的状态值。
  • 网络请求未做错误处理,引发未捕获的Promise拒绝警告。
  • setCurrentIndex()缺乏边界检查,当currDetails为空或结构异常时会抛出运行时错误。

解决方案步骤

1. 修复异步状态依赖

拆分原有的单useEffect为两个独立钩子:

  • 第一个钩子在组件挂载时触发getDetails()获取数据。
  • 第二个钩子监听currDetails的变化,确保状态更新后再执行setCurrentIndex()。

2. 完善错误处理逻辑

在getDetails()中添加try/catch块捕获网络请求和数据解析错误,同时检查HTTP响应状态码确保请求成功。

3. 添加边界防护

在setCurrentIndex()中增加数据结构校验,避免访问未定义属性导致的崩溃。

4. 使用函数式状态更新

更新currDetails时采用函数式更新方式,确保基于最新状态值修改,避免状态不一致问题。

修正后的完整代码

async function getDetails() {
  try {
    const raw = JSON.stringify({ deliveryBoyName: userName });
    const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: raw
    };

    const result = await fetch(apiLink1, requestOptions);
    // 检查HTTP响应是否成功
    if (!result.ok) throw new Error(`请求失败,状态码:${result.status}`);
    
    const jsonResult = await result.json();
    const routedetails = jsonResult.routedetails;

    // 检查是否有有效路由数据
    if (!routedetails || routedetails.length === 0) {
      console.log("未获取到路由详情");
      return;
    }

    if (currDetails.length === 0) {
      const promises = routedetails.map(element => {
        const raw1 = JSON.stringify({
          deliveryBoyName: "mikey",
          deliveryDate: "04-07-2023",
          orderPriority: (element.orderPriority + 30).toString()
        });

        const requestOptions1 = {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: raw1
        };

        return fetch(apiLink2, requestOptions1)
          .then(res => {
            if (!res.ok) throw new Error(`请求失败,状态码:${res.status}`);
            return res.json();
          })
          .then(res => res.routedetails);
      });

      const results = await Promise.all(promises);
      // 函数式更新确保基于最新状态
      setCurrDetails(prevState => [...prevState, ...results]);
    }
  } catch (error) {
    console.error("获取详情失败:", error);
    // 可在此添加用户友好的错误提示,如Toast
  }
}

function setCurrentIndex() {
  try {
    // 边界检查:确保currDetails结构有效
    if (!currDetails || currDetails.length === 0 || !currDetails[0] || !currDetails[0][0]) {
      console.log("currDetails数据无效");
      return;
    }

    setDeliveryNumber(currDetails[0][0].orderPriority);
    for (let i = 0; i < currDetails.length; i++) {
      const currentItem = currDetails[i][0];
      // 校验当前项的属性是否存在
      if (currentItem && currentItem.messagedates && currentItem.messagedates.length === 0) {
        setIndex(i);
        setDeliveryNumber(currentItem.orderPriority);
        break;
      }
    }
  } catch (error) {
    console.error("设置当前索引失败:", error);
  }
}

// 组件挂载时触发数据获取
useEffect(() => {
  getDetails();
}, []);

// 监听currDetails变化,数据就绪后设置索引
useEffect(() => {
  if (currDetails.length > 0) {
    setCurrentIndex();
  }
}, [currDetails]);

关键修改说明

  • 拆分useEffect:通过状态监听确保setCurrentIndex()仅在数据完全更新后执行。
  • 全局错误捕获:覆盖所有网络请求环节的错误处理,消除Promise拒绝警告。
  • 数据校验:提前检查数据结构,避免因异常数据导致的运行时错误。
  • 函数式状态更新:避免并发状态更新导致的数据不一致问题。

内容的提问来源于stack exchange,提问作者Valiveti Swamy Naga Sai Nivas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:29:57