React中useEffect内嵌套异步请求导致数据不渲染问题求助
问题分析与修复方案
核心问题
你的代码存在两个关键问题导致数据无法渲染:
1. 异步请求未正确等待,提前返回空数组
getMatchesWithStats 函数中,使用 map 结合 async/await 时,map 会立即返回一个包含Promise的数组,但函数不会等待这些Promise完成就直接返回了空的 matchesWithStats。此时所有请求还处于pending状态,返回的数组自然没有数据。
2. isLoading 状态管理错误,渲染条件逻辑颠倒
isLoading 初始值为 false,且在请求全程未更新状态,导致渲染条件 {isLoading && matchesRendered} 永远为假——即使后续 matches 有数据,也不会被渲染。
修复代码
1. 修正 getMatchesWithStats 函数
使用 Promise.all 等待所有异步请求完成,同时返回新对象避免修改原数据:
export const getMatches = async () => { const { data } = await axios.get(`https://***/matches`); const filteredLive = data.filter((item: TMatches) => item.live); console.log(filteredLive, 'filteredLive'); return filteredLive; } export const getMatchesWithStats = async (matches: TMatches[]) => { // 用Promise.all等待所有请求完成,返回新的匹配项数组 return Promise.all(matches.map(async (match) => { const { data } = await axios.get(`***/match?id=${match.id}`); // 返回新对象,避免直接修改原match产生副作用 return { ...match, match: data }; })); }
2. 修正组件中的状态管理与渲染逻辑
正确控制 isLoading 状态,调整渲染条件,同时添加错误处理:
export const Matches = () => { const [matches, setMatches] = useState<TMatches[]>([]); const [isLoading, setLoading] = useState<boolean>(true); // 初始设为加载中 useEffect(() => { const getUseMatch = async () => { try { const dataMatches = await getMatches(); const dataMatchesWithStats = await getMatchesWithStats(dataMatches); setMatches(dataMatchesWithStats); } catch (error) { console.error('获取数据失败:', error); // 可添加错误提示逻辑 } finally { setLoading(false); // 请求结束,关闭加载状态 } } getUseMatch(); }, []); const matchesRendered = matches.map((match) => { return ( <> <StyledTeamName variant="h6"> <StyledIconLive> <img src="/live.png" width="32" /> </StyledIconLive> {match.team1.name} - {match.team2.name} </StyledTeamName> <StyledTeamNameSubTitle>{match.event.name}</StyledTeamNameSubTitle> </> ); }); return ( <> {/* 加载时显示提示,加载完成后显示数据 */} {isLoading ? <div>加载中...</div> : matchesRendered} </> ); }
额外说明
- 避免副作用:直接修改原
match对象可能导致意外的状态变化,返回新对象是更安全的做法。 - 错误处理:添加
try/catch可以捕获请求失败的情况,避免组件崩溃,同时可根据需求添加用户友好的错误提示。
内容的提问来源于stack exchange,提问作者user20766085
相关产品推荐
相关产品推荐

