javascript - 如何解决 React Hook 关闭问题?
问题描述
import React, { useState} from "react";
import ReactDOM from "react-dom";
function App() {
const [count, setCount] = useState(0);
function handleAlertClick(){
return (setTimeout(() => {
alert("You clicked on: " + count);
}, 3000))
}
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
我只是想知道这是否像我认为的那样有效,或者是否有更好的解释!
每当setState
调用该方法时,状态都会获得一个新的引用。这意味着原始状态没有新值,而是我们创建具有新值的新状态。当我们单击第二个按钮时,事件处理函数会捕获原始状态的引用。即使我们多次单击第一个按钮,当显示警报时,它也会显示事件处理程序捕获其引用的状态值。
它是否正确?
解决方案
alert
显示过时值的原因count
是因为传递给的回调setTimeout
引用了闭包count
捕获的过时值。这通常被称为stale-closure。
在初始渲染时,匿名函数作为回调传递给setTimeout
捕获count
as的值0
,当单击按钮show alert
时,回调将排队,但 count 的值已过时。
在上述情况下,在警报消息中显示更新的计数值并修复过时关闭问题的最简单解决方案是使用ref
.
function App() {
const [count, setCount] = useState(0);
const latestValue = useRef(count);
const handleAlertClick = () => {
setTimeout(() => {
alert(`count is: ${latestValue.current}`);
}, 3000);
};
return (
<div>
<p>You clicked {count} times</p>
<button
onClick={() => {
setCount(prev => {
latestValue.current = prev + 1;
return prev + 1;
});
}}
>
Click me
</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
Codesandbox中的工作演示
Hooks 在很大程度上依赖于闭包来工作,所以你很可能会遇到关于stale-closures 的问题。这是一篇很好的文章,介绍了在使用 react-hooks 时,stale-closures 如何产生问题,并演示了如何在某些情况下解决一些问题。
推荐阅读
- javascript - 在 ChartJS 中将两个折线图合二为一
- r - 如何同时删除破折号 (-) 和 \n 或对此文本清理的一些解决方案
- java - 由于 Java 即时编译,我是否应该期望 Mockito 测试中的方法中没有的代码运行得更快?
- c# - 修改复杂属性时设置实体状态
- java - 将多个通量合二为一
- python - 姜戈。模型未显示在模板中
- c# - 为什么第二个 from 子句没有在以下 LINQ 查询中执行?
- struct - 将原始二进制结构写入D文件?
- c# - 如何使用反射或类似方法动态提取方法的代码?
- django - Django - 是否有类似于 when2meet.com 的每周日历小部件?