繁体   English   中英

当 useCallback 缺少依赖时 React useState 和 useCallback hook 如何工作

[英]How does React useState and useCallback hook work when useCallback lacks dependencies

我最近在学习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)只打印了 3 次,为什么? 每次点击count++按钮,都会导致Demo function重新执行。 所以每次我点击按钮时,不应该执行console.log('size: ', set.size)吗? 但实际上它只执行了 3 次。

为什么size保持 2 不变? 我知道setCount都会替换一个新的count ,所以size不应该增加?

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

你可以在这里测试我的代码。

Demo组件将在其 state 更改时重新渲染。 因此,当您将计数 state 添加到集合中时,它将具有大小 1:

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

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

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

在接下来的点击中,useCallaback 已经缓存了计数值,但您没有在 useCallback 钩子的第二个参数中设置计数,因此它只会返回缓存值 1 - 计数 state。 它会永远从这里返回。 我再重复一遍,这次设置的大小是 2。

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

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

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


另请注意:不要混淆changeValue在以下点击时不会被调用。 这每次都会调用 useCallback,但它不会更新 state:

  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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM