React实现轮播图时useEffect内setInterval的index变量丢失问题
React轮播图index变量丢失问题修复方案
问题根因
你在组件顶层声明的普通变量index会在每次组件重新渲染时被重新初始化为0,useEffect定时器中对index的修改无法跨渲染持久化,因此触发了React的官方警告。
修复方案1:按提示使用useRef存储index(推荐)
useRef的.current属性存储的可变值不受组件重渲染影响,同时记得补充定时器清除逻辑避免内存泄漏:
const images = [one, two, three, four, five, six, seven]; // 初始化默认展示第一张图 const [currentImage, setCurrentImage] = React.useState(images[0]); // 用useRef存储index,初始值为1(因为第一张已经默认展示了) const indexRef = React.useRef(1); useEffect(() => { const timer = setInterval(() => { setCurrentImage(images[indexRef.current]); indexRef.current++; if (indexRef.current >= images.length) { indexRef.current = 0; } }, 5000); // 组件卸载时清除定时器 return () => clearInterval(timer); }, [images]); // Grid组件不变 <Grid item xs={false} sm={4} md={7} sx={{ backgroundImage: `url(${currentImage})`, backgroundRepeat: "no-repeat", backgroundSize: "cover", backgroundPosition: "center", }} ></Grid>
修复方案2:无需额外维护index,直接用状态函数式更新
如果不想额外引入ref变量,可以直接通过当前的currentImage计算下一张图的索引,逻辑更简洁:
const images = [one, two, three, four, five, six, seven]; const [currentImage, setCurrentImage] = React.useState(images[0]); useEffect(() => { const timer = setInterval(() => { setCurrentImage(prev => { const currentIndex = images.indexOf(prev); const nextIndex = currentIndex + 1 >= images.length ? 0 : currentIndex + 1; return images[nextIndex]; }) }, 5000); return () => clearInterval(timer); }, [images]);
注意事项
- 初始化
currentImage时要传入默认值images[0],避免首次渲染背景为空 - 必须在
useEffect的返回函数中清除定时器,防止组件卸载后定时器继续执行引发报错
内容的提问来源于stack exchange,提问作者Inzamam Baig
相关产品推荐
相关产品推荐

