我知道这可能是个奇怪的情况,但是我试图理解react钩子的内部。
我有一个呈现用于递增计数器的简单按钮的组件和一个使用该按钮的App
组件:
function Comp(props) {
return <button onClick={props.onClick}>Increment</button>;
}
function App() {
const [count, setCount] = useState(5);
const cacheRef = useRef();
const onBtnClick = () => {
console.log(count);
setCount(count + 1);
};
const getIncrementBtn = () => {
if (!cacheRef.current) {
cacheRef.current = <Comp onClick={onBtnClick} />;
}
return cacheRef.current; //this doesn't work
// return <Comp onClick={onBtnClick} />; //this works
};
return (
<div className="App">
<h2>You clicked {count} times!</h2>
{getIncrementBtn()}
</div>
);
}
如果getIncrementBtn
总是返回Comp
的新实例,则一切正常。但是,如果我尝试用Comp
缓存useRef
,则count
总是返回初始值(5
)。如果将setCount(count + 1)
替换为setCount(c => c + 1)
,我可以使其与缓存一起工作,我猜这解决了更新状态的问题,但是count
中的onBtnClick
值仍然是{{ 1}},因此,如果我想基于当前状态进行任何计算,就不会。
我已经找到了解决方法,可以完全丢弃5
并仅使用useState
,但是我更想了解为什么它首先不起作用。我猜想它与闭包有关,并且在某个时候传递了useRef
的副本,但是在阅读了一些文章之后,我不能说我确切地理解了为什么它不按预期工作以及在什么时候工作点count
已被复制。
完整示例:CodeSandbox
任何帮助将不胜感激-可以进行解释,也可以链接到文章/博客以解释count
的这种行为。
谢谢