表单需提交两次才能获取第二个API数据,如何实现单次提交?
问题原因
问题出在React状态更新的异步特性上。你在getFirstAPI里调用setPlayerId后,playerId不会立即更新为新值,所以紧接着执行getSecondAPI(playerId)时,传入的还是更新前的旧值,导致第一次提交时第二个API拿不到正确参数。等第二次提交时,playerId已经是上一次更新后的正确值,才能成功请求到数据。
三种解决方案
方案一:让getFirstAPI返回playerId直接传递
修改getFirstAPI在请求成功后返回res.data.id,这样不用依赖状态更新,就能拿到最新的playerId传给第二个API:
const onFormSubmit = async (searchItem) => { const playerId = await getFirstAPI(searchItem); await getSecondAPI(playerId); }; const getFirstAPI = async (searchItem) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${searchItem}?api_key=${APIKEY}` ); setHaveData(true); setPuuid(res.data.puuid); setPlayerId(res.data.id); setPlayerImage(`${res.data.profileIconId}.png`); console.log(res.data); return res.data.id; // 返回最新playerId }; const getSecondAPI = async (playerId) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${playerId}?api_key=${APIKEY}` ); setPlayerStats(res.data[0]); console.log(res.data[0]); // 直接打印返回值,避免因setPlayerStats异步导致的旧值问题 };
方案二:在getFirstAPI的成功回调里直接调用第二个API
既然已经在请求结果里拿到了res.data.id,直接用这个值调用getSecondAPI,跳过状态的异步更新环节:
const onFormSubmit = async (searchItem) => { await getFirstAPI(searchItem); }; const getFirstAPI = async (searchItem) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${searchItem}?api_key=${APIKEY}` ); setHaveData(true); setPuuid(res.data.puuid); setPlayerId(res.data.id); setPlayerImage(`${res.data.profileIconId}.png`); console.log(res.data); await getSecondAPI(res.data.id); // 直接传入最新的playerId }; const getSecondAPI = async (playerId) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${playerId}?api_key=${APIKEY}` ); setPlayerStats(res.data[0]); console.log(res.data[0]); };
方案三:用useEffect监听playerId变化自动触发请求
这种方式适合需要在playerId更新时自动同步数据的场景,无需在提交函数里手动调用第二个API:
// 新增useEffect监听playerId useEffect(() => { if (playerId) { // 确保playerId有值才发起请求 getSecondAPI(playerId); } }, [playerId]); // 依赖playerId,值变化时执行 const onFormSubmit = async (searchItem) => { await getFirstAPI(searchItem); }; const getFirstAPI = async (searchItem) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${searchItem}?api_key=${APIKEY}` ); setHaveData(true); setPuuid(res.data.puuid); setPlayerId(res.data.id); setPlayerImage(`${res.data.profileIconId}.png`); console.log(res.data); }; const getSecondAPI = async (playerId) => { const res = await axios.get( `https://na1.api.riotgames.com/lol/league/v4/entries/by-summoner/${playerId}?api_key=${APIKEY}` ); setPlayerStats(res.data[0]); console.log(res.data[0]); };
注意:
setPlayerStats同样是异步操作,原代码里的console.log(playerStats)大概率打印的是旧值,建议直接打印res.data[0]查看最新返回结果。
内容的提问来源于stack exchange,提问作者kyle22
相关产品推荐
相关产品推荐

