Reactjs useEffect依赖项列表及其包含所有使用变量的最佳实践
根据使用useEffect依赖项数组时的react文档,您应该传入效果中使用的所有值 如果使用此优化,请确保数组包含组件范围中随时间变化且效果使用的所有值(如道具和状态)。否则,代码将引用以前渲染中的过时值。了解有关如何处理函数的更多信息,以及当数组值更改太频繁时如何执行 我不知道钩子在幕后是如何工作的,所以我在这里猜。 由于闭包中的变量可能会过时,这意味着函数被缓存在某个地方。但是为什么要缓存函数,因为它没有被调用,除非依赖项发生了变化,并且无论如何都需要重新创建函数 我做了一个小的测试组件Reactjs useEffect依赖项列表及其包含所有使用变量的最佳实践,reactjs,react-hooks,use-effect,Reactjs,React Hooks,Use Effect,根据使用useEffect依赖项数组时的react文档,您应该传入效果中使用的所有值 如果使用此优化,请确保数组包含组件范围中随时间变化且效果使用的所有值(如道具和状态)。否则,代码将引用以前渲染中的过时值。了解有关如何处理函数的更多信息,以及当数组值更改太频繁时如何执行 我不知道钩子在幕后是如何工作的,所以我在这里猜。 由于闭包中的变量可能会过时,这意味着函数被缓存在某个地方。但是为什么要缓存函数,因为它没有被调用,除非依赖项发生了变化,并且无论如何都需要重新创建函数 我做了一个小的测试组件
function App() {
const [a, setA] = useState(0);
const [b, setB] = useState(0);
useEffect(() => {
console.log("b", b);
}, [a]);
return (
<div>
<div>App {a}</div>
<button
onClick={() => {
setA(a + 1);
}}
>
AddA
</button>
<button
onClick={() => {
setB(b + 1);
}}
>
AddB
</button>
</div>
);
}
函数应用程序(){
常数[a,setA]=useState(0);
const[b,setB]=useState(0);
useffect(()=>{
控制台日志(“b”,b);
},[a]);
返回(
App{a}
{
刚毛(a+1);
}}
>
阿达
{
挫折(b+1);
}}
>
AddB
);
}
您可以在这里尝试:它工作得很好,没有过时的值。有人能解释一下我遗漏了什么吗
编辑:
在反馈我的问题不完全清楚后,添加一个更具体的问题:
加载页面后,我单击AddB按钮,然后单击AddA按钮,控制台中显示的值为1。根据文档,我应该得到一个过时的值(0)。为什么不是这样
加载页面后,我单击AddB按钮,然后单击AddA 按钮,控制台中显示的值为1。根据文件,我 应获取一个过时的值(0)。为什么不是这样 在这种情况下,您没有看到过时值的原因是,当您单击
AddA
时,会发生重新渲染。在新渲染中,由于a
的值不同于以前的渲染,因此useffect
将计划在用户界面更新后运行(但是,它将引用的值将来自当前渲染-因为传递给useffect
的函数在其依赖项每次更改时都会重新创建,因此它会从该渲染中捕获值)
由于以上原因,这就是为什么您会看到b
的新值
但是如果你有这样的代码
React.useEffect(() => {
const timer = window.setInterval(() => {
setB(b + 1);
}, 1000);
return () => {
window.clearInterval(timer);
};
}, []);
b
将是一个过时的闭包。由于useffect
没有重新运行,b
始终具有创建它的渲染中的值,这是第一个渲染,上面的代码无法按预期工作,您可以自己检查
我将在上面添加Patrick Roberts的这条评论,因为它很好地解释了react文档在说“否则,您的代码将引用以前呈现的过时值”时的含义: 问题是,您必须在第一个窗口中单击AddA按钮 在单击AddB和AddA之间,效果引用 从一个陈旧的结尾
请在问题本身中包含您的代码文本。这并不是说它是否是最佳实践,而是说如果您不包含代码,您不知道实际发生了什么变化。如果您在此处发布代码,我们可以帮助您确定是否存在您可能没有考虑的极端情况。代码在他有一个沙盒链接,但我也将其粘贴到了问题中。你能更清楚地表述你的问题吗?在页面加载后,我单击AddB按钮,然后单击AddA按钮,控制台中显示的值是1。根据文档,我应该得到一个过时的值(0)。为什么不是这样?@gmoniava change
useffect(()=>{console.log(“b”),b);}[a]);
到useffect(()=>{return()=>{console.log(“b”,b);};};}[a]);
。足够好了吗?感谢这个例子,我可以清楚地看到为什么会有问题。所以我可以假设只列出我想“监视”的依赖项吗所以效果会被重新执行,只要我小心它的作用?@Ivan是的,但大多数时候react团队建议列出所有的效果,因为有时候你认为自己很好,不会有过时的结束,但你可能会。