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

React中多下拉列表API调用顺序问题:如何正确获取默认选中项

解决方案:解决异步API加载顺序导致的下拉默认值匹配问题

核心问题分析

你当前的代码里,getAccounts这类异步函数虽然标注了async,但内部调用的UseGet是回调式API,并没有返回Promise,导致await和.then()根本无法等待下拉选项加载完成,getSettingsData会提前执行,此时下拉列表还是空的,自然找不到匹配的ID。

步骤1:把回调式API封装成Promise

首先需要将UseGet包装成支持await的Promise版本,这样才能用Promise来控制异步流程:

// 封装UseGet为Promise函数
function useGetPromise(endpoint, token) {
  return new Promise((resolve, reject) => {
    UseGet(endpoint, token, resolve, (error) => {
      if (error.message === 'not Authorized') {
        setTimeout(() => history.push('/Login'), 1000);
      }
      reject(error);
    });
  });
}

步骤2:重构下拉选项加载函数

将所有下拉选项的加载函数改成基于Promise的异步函数,以getAccounts为例:

async function getAccounts() {
  try {
    const data = await useGetPromise("Account/active-accounts", token);
    const accounts = data?.map(account => ({
      label: account.name?.en,
      value: account.id
    }));
    formik.setFieldValue('accounts', accounts);
  } catch (error) {
    // 错误处理已在封装函数中完成,这里可按需补充
  }
}

同理,把剩下7个下拉选项的加载函数(比如getCategories、getSuppliers等)都改成这种格式。

步骤3:等待所有下拉选项加载完成后再获取默认设置

在useEffect中用Promise.all并行执行所有下拉选项的API请求,等全部完成后再调用getSettingsData:

useEffect(() => {
  // 收集所有下拉选项的API请求
  const allOptionRequests = Promise.all([
    getAccounts(),
    getCategories(),
    getSuppliers(),
    // ... 填入剩下的5个下拉选项API函数
  ]);

  allOptionRequests.then(() => {
    // 所有下拉选项加载完成后,再获取默认设置数据
    getSettingsData();
  }).catch(error => {
    setMessage(error ?? '加载选项数据失败');
    setOpen(true);
    setMessageType('error');
    setIsPending(false);
  });
}, [token, history]);

步骤4:优化默认值匹配逻辑

修改parseSettingsData,增加查找失败的兜底逻辑,避免空对象影响组件:

function parseSettingsData(data) {
  if (!data || Object.keys(data).length === 0) return;

  const matchedAccount = formik.values.accounts?.find(item => 
    item?.value === data?.InverntoryId?.value
  );

  // 找不到匹配项时,用原始ID生成占位项,避免空值
  formik.values.selectedStock = [matchedAccount ?? {
    label: `未找到对应账户(ID: ${data?.InverntoryId?.value})`,
    value: data?.InverntoryId?.value
  }];
}

步骤5:重构默认设置加载函数

同样把getSettingsData改成Promise版本,确保流程可控:

async function getSettingsData() {
  try {
    const data = await useGetPromise("PurchaseSetting/search", token);
    console.log(data);
    formik.setFieldValue('settingsData', data);
    parseSettingsData(data);
    setIsPending(false);
  } catch (error) {
    setMessage(error ?? '获取设置数据失败');
    setOpen(true);
    setMessageType('error');
    setIsPending(false);
  }
}

关键说明

  • 并行加载所有下拉选项API是最优方案,因为这些请求之间没有依赖关系,能大幅缩短加载时间
  • 必须将回调式API转成Promise,才能用await和Promise.all控制异步顺序,这是解决问题的核心
  • 兜底逻辑能避免因ID不存在导致的组件异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:40:30