React批量调用API时setRecords覆盖数组元素而非新增的问题
问题原因与解决方案
问题根源
当你通过Promise.all同时发起多个API请求时,每个makeCall函数中读取的props.records都是组件当前渲染周期的旧状态值——因为所有请求几乎同时启动,此时还没有任何一个请求完成并更新状态。所以每个setRecords执行时,都是把新元素追加到旧的初始数组里,后续的更新会直接覆盖前面的结果,最终只保留最后一条记录。
解决方法
React的setState支持函数式更新,你可以传入一个函数,该函数会接收当前最新的状态作为参数,返回新的状态。这样每次更新都会基于最新的数组状态,不会出现覆盖问题。
修改Request.tsx中的setRecords调用
将原来基于旧props.records的更新方式,改为函数式更新:
props.setRecords(prevRecords => [ { // 注意:原代码中props.key是React组件的特殊属性,不能直接用作记录的key,建议生成唯一值 key: `${Date.now()}-${Math.random()}`, response: data.body }, ...prevRecords ]);
可选:统一makeCall的代码风格(async/await版)
原代码混用了await和.then,可以统一为更清晰的async/await风格:
const makeCall = async (inputText: string, option: string) => { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(inputText) }); const data = await response.json(); props.setRecords(prevRecords => [ { key: `${Date.now()}-${Math.random()}`, response: data.body }, ...prevRecords ]); } catch (error) { console.log(error); } };
修改后,每个API请求完成后都会基于最新的records数组追加新元素,不会再出现覆盖问题。
内容的提问来源于stack exchange,提问作者vallycat734
相关产品推荐
相关产品推荐

