React中使用axios取数时如何等待Promise完成后再使用结果
问题根源
- async函数的返回值永远是Promise对象,就算内部使用了await,调用
getDoH()时同步拿到的还是Promise,只有等它resolve之后才能拿到接口返回的真实数据 - useState的初始化函数是同步执行的,React不会等待内部异步逻辑执行完成再完成state初始化,所以你现在
initialValues的初始值就是你返回的Promise对象,直到接口请求完成调用setInitialValues之后,initialValues才会变成接口返回的真实数据 - 在useState初始化函数内部调用
setInitialValues属于冗余且不符合规范的写法,初始化阶段state还没挂载完成,此时调用setState不会生效
解决方案
步骤1:修改initialValues的初始化逻辑,用useEffect触发异步请求
// 初始值设为null,标识数据还未加载完成 const [initialValues, setInitialValues] = useState(null); // 新增加载状态,方便处理加载中、错误等边界场景 const [loading, setLoading] = useState(true); // 组件挂载后执行异步请求 useEffect(() => { const fetchInitData = async () => { try { const response = await getDoH(); setInitialValues(response.data); } catch (error) { console.log(error); } finally { setLoading(false); } }; fetchInitData(); }, []); // 空依赖数组,组件挂载时仅执行一次
步骤2:等待initialValues加载完成后再计算values
方案A:如果values后续需要单独修改,用useEffect监听数据加载状态
const [values, setValues] = useState({}); const setStartValues = (initData) => { // 替换成你自己的初始变量模板 let newValues = {}; let valueArray = Object.entries(newValues).map((v, index) => { v[1] = initData.switchValues[index]; return v; }); newValues = Object.fromEntries(valueArray); setValues({...newValues}); }; // 监听initialValues和loading的变化,数据加载完成后再执行赋值 useEffect(() => { if (!loading && initialValues) { setStartValues(initialValues); } }, [initialValues, loading]);
方案B:如果values完全由initialValues计算生成,不需要单独修改,用useMemo更简洁
const values = useMemo(() => { // 数据未加载完成时返回空对象,也可以返回自定义的默认值 if (!initialValues) return {}; // 替换成你自己的初始变量模板 let newValues = {}; let valueArray = Object.entries(newValues).map((v, index) => { v[1] = initialValues.switchValues[index]; return v; }); return Object.fromEntries(valueArray); }, [initialValues]);
内容的提问来源于stack exchange,提问作者Mr.Gomer
相关产品推荐
相关产品推荐

