为何监听useRef变化的useEffect仅触发一次console.log?期望每秒执行
问题分析与解决方案
核心问题原因
React的useEffect只有在组件发生重渲染时才会重新计算依赖项并执行副作用。而useRef的current属性修改不会触发组件重渲染,所以你给第一个useEffect设置的[changeRef.current]依赖完全无效——组件没重渲染,React不会去检查这个依赖是否变化,自然只会在首次渲染时执行一次。
解决方案1:无需组件重渲染,仅实现每秒打印
直接在定时器内同步更新prevValueRef并打印,不需要借助useEffect监听:
const PreviousValueComponent = ({ value }) => { const prevValueRef = useRef(); const changeRef = useRef(value); useEffect(() => { const interval = setInterval(() => { prevValueRef.current = changeRef.current; console.log(`prevValueRef is: ${prevValueRef.current}`); changeRef.current++; }, 1000); // 组件卸载时清理定时器,避免内存泄漏 return () => clearInterval(interval); }, []); return ( <div> <p>Current Value: {value}</p> <p>Previous Value: {prevValueRef.current}</p> </div> ); };
解决方案2:需要页面UI同步更新(可选)
如果要让页面上的Previous Value文本实时更新,必须用useState触发组件重渲染(因为ref变化不会更新UI):
const PreviousValueComponent = ({ value }) => { const [prevValue, setPrevValue] = useState(value); const changeRef = useRef(value); useEffect(() => { const interval = setInterval(() => { changeRef.current++; setPrevValue(changeRef.current); console.log(`prevValueRef is: ${changeRef.current}`); }, 1000); return () => clearInterval(interval); }, []); return ( <div> <p>Current Value: {value}</p> <p>Previous Value: {prevValue}</p> </div> ); };
对补充问题的答复
你的实现方式确实有误:useEffect的依赖更新机制依赖组件重渲染,而ref.current的修改不会触发重渲染,所以React不会重新检查该依赖项,也就不会执行副作用。如果要监听ref变化,要么在修改ref的地方直接执行逻辑,要么结合useState触发重渲染让React重新计算依赖。
内容的提问来源于stack exchange,提问作者Arman Ebrahimi
相关产品推荐
相关产品推荐

