#闭包陷阱
下方的 useEffect 的引用始终是初次渲染创建的 latestCount 的值
再 setCount 触发后,count 会正常更新,但是定时器的打印会错误
jsxfunction Counter() { const [count, setCount] = useState(0) // count = 0 let latestCount = count // ① latestCount₁ = 0(内存地址A) useEffect(() => { latestCount = count // ② ✅ 首次渲染会执行!latestCount₁ = 0 }) useEffect(() => { const timer = setInterval(() => { console.log('Latest count:', latestCount) // ③ 闭包捕获 latestCount₁,始终打印0 }, 1000) return () => clearInterval(timer) }, []) // ④ ✅ 首次渲染也会执行! return ( <> <h2>{count}</h2> <button class onClick={() => setCount(1)}> Click </button> </> ) }
#解决闭包陷阱
useRef返回的对象{ current: value }在整个组件生命周期内引用不变- 现在闭包捕获的是
latestCountRef这个对象引用 - 通过
latestCountRef.current访问时,总是读取最新的值
tsxfunction Counter2() { const [count, setCount] = useState(0) let latestCountRef = (useRef < null) | (number > null) useEffect(() => { latestCountRef.current = count }) useEffect(() => { const timer = setInterval(() => { console.log('Latest count2:', latestCountRef.current) }, 1000) return () => clearInterval(timer) }, []) return ( <> <h2>{count}</h2> <button className="btn btn-primary" onClick={() => setCount(count + 1)}> Click </button> </> ) }
#useRef 的应用场景
- 场景 1: 事件监听器
- 场景 2: 定时器
useRef 是 React 中处理回调函数依赖的最佳实践之一
