React中movieinfos含7条数据但map仅渲染1条电影卡片问题排查
问题原因与修复方案
核心原因
- 你声明的
moviesData是普通可变数组,数组属于引用类型,你每次往数组中push数据后调用setMovieinfos(moviesData),传入的始终是同一个数组引用。React状态更新会做浅比较,当发现传入的引用和当前存储的movieinfos引用一致时,会认为状态没有发生变化,直接跳过后续重渲染。 - 只有第一次
push后调用setMovieinfos时,空数组的引用被替换为包含1条数据的数组引用,触发了一次重渲染,后续6次更新因为引用没有变化全部被跳过,因此页面仅显示1条卡片。你在控制台看到数组包含7条数据,是因为控制台打印数组时保存的是内存引用,你展开查看时数组已经被后续的异步请求push完所有数据,并非渲染时的真实状态。 - 额外隐患:多个异步请求的返回顺序不确定,直接循环发送请求逐个更新状态,很容易出现数据顺序错乱、丢失的问题。
修复方案
修改处理电影详情请求的useEffect逻辑,删除外部声明的moviesData变量,改用Promise.all等待所有请求完成后一次性更新状态,彻底避免引用问题和顺序问题:
useEffect(() => { // movieid为空时直接返回不执行逻辑 if(!movieid.length) return // 生成所有请求的Promise数组 const requestList = movieid.map(movie => axios.get(`${BASE_URL}${movie.movieid}?api_key=${API_KEY}&language=fr`) .then(response => ({ Genres: response.data.genres, Overview: response.data.overview, Poster: response.data.poster_path, Company: response.data.production_companies, Release: response.data.release_date, Title: response.data.title })) ) // 等待所有请求完成后一次性更新状态 Promise.all(requestList) .then(allMoviesData => { setMovieinfos(allMoviesData) }) .catch(error => console.log(error)) }, [movieid])
内容的提问来源于stack exchange,提问作者user16697052
相关产品推荐
相关产品推荐

