React中如何多次调用同一API并传入不同JSON数据?
问题分析与优化方案
问题根源
- React状态更新的异步性:
setUserData是异步操作,调用后不会立即更新userData状态。你在synchToLocation里先调用setUserData,紧接着就用userData构造请求体,此时userData还是更新前的旧值。 - 闭包捕获旧值:连续三次调用
synchToLocation时,三个函数实例会捕获同一个userData闭包值,导致三次请求都使用初始的旧数据,最终可能只有最后一次的更新生效。
优化方案
方案1:直接使用新生成的数据(并行请求)
不需要依赖异步更新的状态,先构造出要发送的新数据,同时用它更新状态和发送请求,确保每次请求的数据都是正确的。
修改synchToLocation函数:
const synchToLocation = (loc) => { // 先构造新的用户数据对象 const newUserData = {...userData, id: 1234, location: loc}; // 更新状态 setUserData(newUserData); // 用新数据发送请求 const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newUserData) }; fetch("http://localhost:8080/api/v1/synch", requestOptions); };
方案2:串行执行请求(确保顺序依赖)
如果需要三次请求严格按顺序执行,且后一次请求基于前一次更新后的状态,需要将请求改为串行调用,同时利用setUserData的函数式更新确保获取最新状态。
- 修改
synchToLocation为异步函数,返回Promise:
const synchToLocation = async (loc) => { return new Promise((resolve, reject) => { setUserData(prevUserData => { const newUserData = {...prevUserData, id: 1234, location: loc}; const requestOptions = { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(newUserData) }; // 发送请求并处理结果 fetch("http://localhost:8080/api/v1/synch", requestOptions) .then(res => resolve(res)) .catch(err => reject(err)); return newUserData; }); }); };
- 修改
handleSynch为异步函数,串行调用:
const handleSynch = async () => { try { await synchToLocation(1); await synchToLocation(2); await synchToLocation(3); } catch (err) { console.error("同步请求出错:", err); } };
额外优化:修正fetchUser的闭包问题
将fetchUser中的setUserData改为函数式更新,避免闭包捕获旧状态,同时修正函数拼写错误:
// 修正拼写错误:fecthUser → fetchUser const fetchUser = (event) => { event.preventDefault(); console.log(userid); fetch(`http://localhost:8080/api/v1/synch/emp?id=${userid}`) .then(result => result.json()) .then(e => { setUserData(prev => ({ ...prev, id: e.id, firstName: e.firstName, lastName: e.lastName, role: e.role, location: e.location, status: e.status })); }); };
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

