import React, { useState, useEffect, useRef, useCallback } from 'react';
function ClosureTrapDemo() {
const [count, setCount] = useState(0);
const latestCount = useRef(count);
// 问题示例1: useState闭包陷阱
const badIncrement = () => {
setCount(count + 1);
console.log('Bad increment:', count); // 旧值
};
// 解决方案1: 函数式更新
const goodIncrement = () => {
setCount(prev => prev + 1);
console.log('Good increment:', count); // 仍为旧值(渲染未完成)
};
// 问题示例2: useEffect闭包陷阱
useEffect(() => {
const timer1 = setInterval(() => {
console.log('Bad interval count:', count); // 总是初始值
}, 1000);
return () => clearInterval(timer1);
}, []);
// 解决方案2: 正确声明依赖
useEffect(() => {
const timer2 = setInterval(() => {
console.log('Good interval count:', count); // 最新值
}, 1000);
return () => clearInterval(timer2);
}, [count]);
// 解决方案3: 使用useRef
useEffect(() => {
latestCount.current = count;
});
useEffect(() => {
const timer3 = setInterval(() => {
console.log('Ref count:', latestCount.current); // 最新值
}, 1000);
return () => clearInterval(timer3);
}, []);
// 解决方案4: 使用useCallback
const showCount = useCallback(() => {
alert(`Current count: ${count}`);
}, [count]);
return (
<div>
<h2>Count: {count}</h2>
<button onClick={badIncrement}>Bad Increment</button>
<button onClick={goodIncrement}>Good Increment</button>
<button onClick={showCount}>Show Count</button>
</div>
);
}
export default ClosureTrapDemo;