gpt4 book ai didi

javascript - 当 useCallback 缺乏依赖项时,React useState 和 useCallback hook 如何工作

转载 作者:行者123 更新时间:2023-12-01 00:27:03 28 4
gpt4 key购买 nike

最近在研究react-hook。我在实践的过程中遇到了一个让我无法理解的问题。

import React, { useState, useCallback } from 'react';
const set = new Set();

function Demo() {
const [count, setCount] = useState(0);

const changeValue = useCallback(() => {
setCount(count + 1);
}, []);

set.add(count);
console.log('size: ', set.size);

return(
<div>
<p>Hello React Hook</p>
<p>{count}</p>
<button onClick={changeValue}>count++</button>
</div>
)
}

export default Demo;

// If you click the button multiple times, the output is:
// size: 1
// size: 2
// size: 2

我使用react-hook编写了一个计时器。正如我所料,显示的计数值始终为 1,因为我没有使用 count 作为 useCallback 的依赖项。

但是我不明白的是 console.log('size: ', set.size) 只打印了三次,为什么?每次我点击count++按钮,都会导致Demo函数重新执行。那么每次点击按钮时,不应该执行 console.log('size: ', set.size) 吗?但实际上只执行了3次。

为什么size保持2不变?我知道 setCount 每次都会替换一个新的 count,因此 size 不应增加?

请大家帮我解答疑惑,非常感谢。

你可以测试我的代码here .

最佳答案

只要状态发生更改,Demo 组件就会重新渲染。因此,当您将计数状态添加到集合中时,它将具有大小 1:

set.add(count); // 0 in initial render, size is 1

现在,当您单击按钮时,它将使用由react存储的回调useCallback。这意味着它将首先检查是否有缓存值。因此,第一次单击时它没有缓存值。因此它调用回调来设置(更新)计数状态。现在,计数为 1,并且您还将计数添加到集合中。

set.add(count); // 1 in first click, size is 2

在接下来的点击中,useCallaback 已缓存计数值,但您尚未在 useCallback Hook 的第二个参数中设置计数,因此它只会返回缓存值 1 - 计数状态。它总是会从此返回。我再次重复一遍,这次设置的大小是 2。

将计数状态放入第二个参数时,您应该注意变化:

  const changeValue = useCallback(() => {
setCount(count + 1);
}, [count]); // we watch it on every click

现在,每次单击按钮时您都会看到不断变化的值。

<小时/>

另请注意:不要混淆 changeValue 不会在以下点击中被调用。这每次都会调用 useCallback 但它只是不更新​​状态:

  const changeValue = useCallback(() => {
console.log('clicked') // logged every time on button click
setCount(count + 1); // count state is not being watched,
// setCount won't update the count on following clicks
// once it caches the state.
},[]); // need to watch state here to update the state

关于javascript - 当 useCallback 缺乏依赖项时,React useState 和 useCallback hook 如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58889664/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com