useEffect中处理的数据未渲染,控制台输出正常但模板中变量为undefined
问题根源
- 你声明的
movieRows是组件内部的普通临时变量,不属于React响应式状态,对它赋值不会触发组件重新渲染 useEffect的执行时机晚于组件的渲染阶段,组件首次执行return输出模板时,useEffect内的赋值逻辑还未运行,movieRows仍为初始值undefined。即使后续useEffect内完成赋值,由于没有触发重渲染,模板读取到的值也不会更新。
解决方案
不需要把逻辑放到useEffect中,直接将movieRows的计算逻辑放到渲染阶段,用useMemo缓存计算结果即可,修改后代码如下:
// MovieOverview.tsx import { useMemo, useEffect, useState } from 'react'; const MovieOverview = () => { const {data} = useQuery(resolvers.queries.ReturnAllMovies); const movie: IMovie = useReactiveVar(moviesVar); // 可选:如果需要响应窗口大小变化,添加窗口宽度监听 const [windowWidth, setWindowWidth] = useState(window.innerWidth); useEffect(() => { const handleResize = () => setWindowWidth(window.innerWidth); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); const movieRows = useMemo(() => { let movies = data?.movies || []; if (movie) { movies = movies.concat(movie); } if (!movies.length) return []; const numberOfMovies = Math.floor((windowWidth - 24) / 185); return chunk(movies, numberOfMovies); }, [data?.movies, movie, windowWidth]); // 依赖变化时自动重新计算 return ( <div> {movieRows.length} </div> ); };
这样依赖项变化时useMemo会自动重新计算movieRows的值,并且会触发组件使用最新值渲染,同时还能支持窗口大小变化时自动调整每行的电影数量。
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

