2023年React结合Axios与useEffect的最佳实践及异步问题解决
React中useEffect结合Axios异步获取数据的最优方案
你遇到的核心问题是:getTransactions作为async函数,调用后必然返回Promise对象,直接赋值给变量并传给setTransactions自然无法得到预期的真实数据。不需要用.then链式调用,现在用async/await就能写出更简洁的代码,同时保证只请求一次数据。
推荐方案一:useEffect内部定义异步函数
在useEffect内部单独定义一个异步函数再调用——注意不要直接把useEffect的回调写成async(会导致返回Promise,不符合useEffect对返回值的要求)。
useEffect(() => { const fetchTransactions = async () => { const data = await getTransactions(); // 考虑到请求失败时getTransactions可能返回undefined,做个判断 if (data) { setTransactions(data); } }; fetchTransactions(); }, []); // 空依赖数组确保组件挂载时仅执行一次
推荐方案二:立即执行异步函数(IIFE)
如果觉得单独定义函数有点冗余,可以用立即执行函数的写法,代码更紧凑:
useEffect(() => { (async () => { const data = await getTransactions(); if (data) { setTransactions(data); } })(); }, []);
额外优化建议
你的getTransactions函数在catch中只打印错误但没有抛出或返回默认值,这会导致请求失败时返回undefined。建议补充错误处理逻辑,让调用方更可控:
export const getTransactions = async () => { try { const response: any = await axios.get('transactions'); return response.data.transactions; } catch (e) { console.error('Get Transactions Error', e); // 可选:抛出错误让调用方处理 throw e; // 或者返回空数组作为默认值 // return []; } };
如果选择抛出错误,调用时可以添加try-catch处理失败场景:
useEffect(() => { const fetchTransactions = async () => { try { const data = await getTransactions(); setTransactions(data); } catch (e) { // 这里可以处理请求失败的逻辑,比如设置错误提示 console.error('Failed to fetch transactions', e); } }; fetchTransactions(); }, []);
内容的提问来源于stack exchange,提问作者Time Buy
相关产品推荐
相关产品推荐

