最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How does React useState and useCallback hook work when useCallback lacks dependencies - Stack Overflow

programmeradmin5浏览0评论

I am studying react-hook recently. I have encountered a problem which makes me unable to understand in the process of practice.

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

I wrote a timer using react-hook. As I expected, the count value shown is always 1, because I didn't use count as a dependency of useCallback.

But what I can't understand is console.log('size: ', set.size) only printed three times, why? Every time I click the count++ button, it will cause the Demo function to re-execute. So every time I click the button, shouldn't console.log('size: ', set.size) will be executed? But in fact it only executed three times.

And why does size keep 2 unchanged? I understand that setCount will replace a new count every time, so size should not increase?

Please help me answer my doubts, thank you very much.

You can test my code here.

I am studying react-hook recently. I have encountered a problem which makes me unable to understand in the process of practice.

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

I wrote a timer using react-hook. As I expected, the count value shown is always 1, because I didn't use count as a dependency of useCallback.

But what I can't understand is console.log('size: ', set.size) only printed three times, why? Every time I click the count++ button, it will cause the Demo function to re-execute. So every time I click the button, shouldn't console.log('size: ', set.size) will be executed? But in fact it only executed three times.

And why does size keep 2 unchanged? I understand that setCount will replace a new count every time, so size should not increase?

Please help me answer my doubts, thank you very much.

You can test my code here.

Share Improve this question asked Nov 16, 2019 at 10:17 DangoSkyDangoSky 2351 gold badge4 silver badges15 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 10

The Demo ponent will re-render whenever its state is changed. So, it will have the size 1 as you have added count state to the set:

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

Now, when you click on the button, it will use the callback useCallback that is memoized by react. It means it will first check if has cached value or not. So, at the first click it has no cached value. And thus it calls its callback to set (update) the count state. Now, count is 1 and you also added the count in to the set.

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

On following clicks useCallaback has cached the count value but you have not set the count in second parameter of useCallback hook and thus it will just return the cached value that is 1 - the count state. And it will return always from this. Again I repeat, this time the set size is 2.

You should watch for the changes when put the count state in second argument:

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

Now, you will see the changing value each time you click on the button.


Also note: Don't confuse the changeValue is not being called on following clicks. This calls the useCallback every time but it just doesn't update the 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

I'm also a React beginner but watching your question I found something.

I think you already know the internal motions of useState and useCallback,

But the reason why print size: 2 message is printed whenever you click is

the type of set variable is Set

the variable with Set type doesn't keep duplicate values inside.

(I think you might already know this but I think you missed it because you are in struggle of React)

so it is far from React I think.

And why it only printed three times is .. I think it is because an optimization of React but it is not sure because I'm also beginner

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论