React中循环获取数据后调用setState不生效问题求助
问题原因及修复方案
你的核心问题是异步请求没等待完成就更新状态:在arr.forEach里发起的fetch是异步操作,代码会直接跳过这些请求执行setWatched(w),此时w还是空数组,页面自然没内容。
具体修复步骤:
- 把
arr.forEach换成Promise.all,等待所有TMDB的API请求完成后再更新状态 - 简化Firebase数据的提取逻辑,不用手动循环push数组
- 增加
auth.currentUser的空值判断,避免未登录时出现报错
修复后的完整代码:
useEffect(() => { getWatched(); }, []); const getWatched = async () => { try { // 先判断用户是否登录 if (!auth.currentUser) return; // 简化Firebase数据提取 const snapShot = await getDocs( collection(db, "users", auth.currentUser.uid, "Watched") ); const arr = snapShot.docs.map(doc => doc.data()); // 用Promise.all等待所有API请求完成 const promises = arr.map(obj => { const showType = obj.show ? "movie" : "tv"; const link = `https://api.themoviedb.org/3/${showType}/${obj.id}?api_key=${process.env.REACT_APP_MOVIE_DB}&language=en-US`; return fetch(link).then(res => res.json()); }); const watchedData = await Promise.all(promises); setWatched(watchedData); console.log("Got Data"); } catch (error) { console.log(error); } };
额外优化建议:
- 在组件里增加加载状态,比如
const [isLoading, setIsLoading] = useState(true),请求开始时设为true,完成后设为false,页面上可以显示加载提示,提升用户体验 - 可以给
fetch请求加超时处理,避免一直等待无响应的请求
内容的提问来源于stack exchange,提问作者Akhil Bisht
相关产品推荐
相关产品推荐

