React/JavaScript如何实现多个fetch请求并分类存储返回数据
实现方案
你原有代码存在两个核心问题:
- 在
Promise.all的参数数组中给每个fetch加await,会让两个请求从并发变成串行执行,白白增加请求总耗时 response.json()本身返回Promise对象,你没有等待它解析完成就赋值,最终拿到的会是Pending状态的Promise,不是实际接口数据;而且普通变量赋值不会触发React组件重渲染,数据更新后页面不会同步刷新
基于useEffect+useState的标准实现
直接在useEffect里发起并发请求,用独立的useState存储不同接口的返回值即可,同时可以补充加载状态、错误处理的逻辑,适配实际业务场景:
import { useState, useEffect } from 'react'; function DataComponent() { // 为不同接口单独定义state,初始值可以根据接口返回类型设置为数组/空对象 const [timeData, setTimeData] = useState([]); const [functionData, setFunctionData] = useState([]); // 可选:补充加载、错误状态,优化用户体验 const [loading, setLoading] = useState(false); const [errorMsg, setErrorMsg] = useState(''); useEffect(() => { // useEffect的回调不能直接声明为async,所以在内部定义异步请求函数 const loadAllData = async () => { try { setLoading(true); setErrorMsg(''); // 直接传入fetch任务实现真正并发,不要在数组内加await const [timeResponse, funcResponse] = await Promise.all([ fetch('/api/time-endpoint'), fetch('/api/function-endpoint') ]); // fetch仅在网络异常时抛出错误,HTTP 4xx/5xx需要手动校验 if (!timeResponse.ok) throw new Error('时间数据接口请求失败'); if (!funcResponse.ok) throw new Error('功能数据接口请求失败'); // 并发解析两个响应的JSON结果 const [timeResult, funcResult] = await Promise.all([ timeResponse.json(), funcResponse.json() ]); // 分别更新对应state,触发组件重渲染 setTimeData(timeResult); setFunctionData(funcResult); } catch (err) { setErrorMsg(err.message); } finally { setLoading(false); } }; loadAllData(); }, []); // 空依赖数组表示仅在组件首次挂载时执行一次请求 // 渲染时可以根据状态做对应处理 if (loading) return <div>数据加载中...</div>; if (errorMsg) return <div>加载失败:{errorMsg}</div>; return ( <div> {/* 后续逻辑里可以直接访问timeData、functionData使用 */} </div> ); }
可选优化点
- 如果接口数量多,不想定义太多独立state,也可以合并为单个state对象管理:
const [apiData, setApiData] = useState({ timeData: [], functionData: [] }); // 更新时 setApiData({ ...apiData, timeData: timeResult, functionData: funcResult });
- 如果后续需要手动触发重新请求,只需要把
loadAllData函数从useEffect中提取出来,绑定到按钮点击等事件上即可 - 如果组件卸载时请求还没完成,可以加AbortController中断请求,避免内存泄漏
内容的提问来源于stack exchange,提问作者salteax1
相关产品推荐
相关产品推荐

