React使用Axios批量请求TMDB数据 状态仅保留最后一条如何解决
问题根因
- 状态更新语法错误:
setMovieinfos接收的参数应该是完整的新状态值,你当前的写法setMovieinfos(...movieinfos, response.data)相当于把数组元素展开作为独立参数传给setter,实际上只有第一个展开值会被当作新状态,后续参数全部被忽略。 - 闭包陷阱:所有异步请求的回调函数都捕获了本次
useEffect执行时的movieinfos初始值(空数组),每次更新都是基于空数组拼接单个数据,前面的请求返回的更新会被后面的覆盖,最终只保留最后一个请求的结果。
修复方案
方法1:使用setState函数式更新(快速修复)
函数式更新可以拿到最新的状态值,不会受闭包影响,同时传递完整的新数组即可:
把原来的代码:
setMovieinfos(...movieinfos, response.data);
修改为:
setMovieinfos(prev => [...prev, response.data]);
方法2:批量请求后一次性更新(推荐,性能更优)
用Promise.all等待所有请求完成后一次性更新状态,减少多次状态更新触发的重渲染次数:
useEffect(() => { if (!movieid.length) return; // 生成所有请求的Promise数组 const requestList = movieid.map(movie => axios.get(`${BASE_URL}${movie.movieid}?api_key=${API_KEY}&language=fr`) .then(res => res.data) .catch(err => { console.log(err); // 单个请求失败时返回占位值,避免整个Promise.all中断 return null; }) ); // 等待所有请求完成后批量更新状态 Promise.all(requestList).then(movieList => { // 过滤掉请求失败的空值 setMovieinfos(movieList.filter(Boolean)); }) }, [movieid]);
map遍历渲染说明
修复后movieinfos是标准数组类型,可以直接调用map方法遍历渲染,示例写法:
<div className="Movies"> {movieinfos.map((movie) => ( <Movie_card key={movie.id} movieInfo={movie} /> ))} </div>
注意:请使用电影详情中的唯一id作为key值,不要用遍历下标index作为key
内容的提问来源于stack exchange,提问作者user16697052
相关产品推荐
相关产品推荐

