React如何迭代更新状态并限制最多2个键值对?
解决方案
首先修复代码里的异步遍历问题,forEach中使用await不会按顺序等待请求完成,建议改用for...of或者Promise.all处理异步请求。然后在更新state时加入键数量限制逻辑,确保最终data中最多保留2个键值对。
方案1:保留最新的2个键值对(新键加入时移除最早的旧键)
适合需要处理所有传入的ids,但最终只保留最新2个数据的场景:
const App = ({ ids }) => { const [data, setData] = useState<Record<number, Record[]>>({}); useEffect(() => { const callAPI = async () => { // 用for...of保证异步请求按顺序执行 for (const id of ids) { try { const result = await axios.post("example.com", { id }); setData((prev) => { // 如果当前id已存在,直接更新对应数据 if (prev.hasOwnProperty(id)) { return { ...prev, [id]: result ?? [] }; } const currentKeys = Object.keys(prev) as string[]; // 键数量不足2个,直接添加新键值对 if (currentKeys.length < 2) { return { ...prev, [id]: result ?? [] }; } // 键数量已满,移除最早加入的键(Object.keys按插入顺序返回) const newData = { ...prev }; delete newData[currentKeys[0]]; newData[id] = result ?? []; return newData; }); } catch (err) { console.error(`请求id ${id}失败`, err); } } }; callAPI(); }, [ids]); return <div>{/* 渲染内容 */}</div>; };
方案2:仅请求前2个id(从源头控制,避免多余请求)
如果只需要保留前2个ids对应的数据,可以直接限制请求范围,从源头避免state超过2个键值对:
const App = ({ ids }) => { const [data, setData] = useState<Record<number, Record[]>>({}); useEffect(() => { const callAPI = async () => { // 只取传入ids的前2个 const targetIds = ids.slice(0, 2); // 并行发起请求 const requests = targetIds.map(async (id) => { const result = await axios.post("example.com", { id }); return { id, data: result ?? [] }; }); try { const results = await Promise.all(requests); // 将请求结果组装成目标格式 setData(results.reduce((acc, { id, data }) => { acc[id] = data; return acc; }, {} as Record<number, Record[]>)); } catch (err) { console.error("请求失败", err); } }; callAPI(); }, [ids]); return <div>{/* 渲染内容 */}</div>; };
关键逻辑说明
- 方案1会处理所有传入的
ids,但始终保证state里最多2个键值对,新数据加入时自动剔除最早的旧数据 - 方案2直接减少不必要的API请求,只获取前2个
ids的数据,更适合明确只需要少量数据的场景 - 两种方案都加入了错误捕获,避免单个请求失败导致整个流程中断
内容的提问来源于stack exchange,提问作者Julia
相关产品推荐
相关产品推荐

