使用setInterval时索引无法自动重置的React技术问题
问题原因
你的代码里setInterval的回调函数陷入了闭包陷阱:当handleClick执行时,回调捕获的是当时的i值(初始为0),后续组件重新渲染时,这个回调里的i不会同步更新,始终保持初始的0。所以i < 10永远成立,setI(prev => prev + 1)会持续执行,索引自然不会重置。
解决方案
方案1:在函数式更新中处理逻辑
把判断逻辑移到setI的函数式更新回调里,这里能拿到最新的状态值,同时添加定时器清理逻辑避免内存泄漏:
export default function Gallery() { const [i, setI] = useState(0); const timerRef = useRef(null); function handleClick() { // 避免重复创建定时器 if (timerRef.current) clearInterval(timerRef.current); timerRef.current = setInterval(() => { setI(prev => prev < 10 ? prev + 1 : 0); }, 1000); } // 组件卸载时清理定时器 useEffect(() => { return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, []); console.log(i); return ( <button onClick={handleClick}>开始轮播</button> ); }
方案2:用useRef跟踪最新状态
如果需要在定时器回调中直接访问最新的索引值,可以用useRef同步状态:
export default function Gallery() { const [i, setI] = useState(0); const indexRef = useRef(i); const timerRef = useRef(null); // 同步ref与state useEffect(() => { indexRef.current = i; }, [i]); function handleClick() { if (timerRef.current) clearInterval(timerRef.current); timerRef.current = setInterval(() => { if (indexRef.current < 10) { setI(prev => prev + 1); } else { setI(0); } }, 1000); } useEffect(() => { return () => { if (timerRef.current) clearInterval(timerRef.current); }; }, []); console.log(i); return ( <button onClick={handleClick}>开始轮播</button> ); }
内容的提问来源于stack exchange,提问作者Abdulbasit Yusuf
相关产品推荐
相关产品推荐

