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
相关产品推荐
相关产品推荐

