2
votes

When the state changes, to what extent the component is updated? Let's say, when state A changes, I can read the console log of render in Component. I'm wondering what happens to the statement useState since the initial value is set at 1 because the initial value should not be ignored. When I call someFunction, a now becomes 2, but if rerendering occurs, what does happen to const [a,setA] = useState(1)?

For useEffect, when state A changes, I also think useEffect is re-claimed (and for sure, dependency has changed!), but what happen to the previously stated version of useEffect?

Whenever I click the button, new version of useState and useEffect are generated, and what happen to the old versions of these pairs? Are they being stored into some kind of memory of browsers? Judging from the react debugger, we can navigate to the previous look with the previous state values, which means the snapshots of the states are somehow stored. I am super curious where they are! If that's true, when certain amount state changes exceeds the memory limit, would our app be in crisis?

Looking forward to getting any feedbacks about this question!

const Component = () => {
  console.log('render component');
  const [a, setA] = useState(1);
  
  const someFunction = () => {
    console.log('some function')
    setA(prev=>prev+1)
  }

  useEffect(() => {
    console.log('use effect')  
    console.log(a);
  }, [a])
 
  return <>
    <div onClick={someFunction}>Click</div>
  </>
  
}

2

2 Answers

1
votes

what happens to the statement useState since the initial value is set at 1 because the initial value should not be ignored

When a component first mounts, any useStates used inside it create a value mapped to that state in React's internals. The initial value for that is the argument passed to useState. It may be like an array. For example, if you have

const [a, setA] = useState(1);
const [b, setB] = useState(5);

Then, once the component renders, React is storing internally something like

[1, 5]

corresponding to the first and second states.

When you set state, the corresponding value in React's internals changes. For example, if you ran, once:

setA(prev=>prev+1)

React would then have

[2, 5]

And then the component would re-render. On re-renders, the initial state (passed to useState) is ignored - instead, the stateful value is taken from the value in React internals. So with

const [a, setA] = useState(1);
const [b, setB] = useState(5);

on re-render, a evaluates to 2, and b evaluates to 5.

what happen to the old versions of these pairs?

The old values may get garbage collected if nothing can reference them anymore. (The state setter functions are stable.)

For useEffect, when state A changes, I also think useEffect is re-claimed (and for sure, dependency has changed!), but what happen to the previously stated version of useEffect?

Yes, with a new render, prior useEffect callback functions will eventually get garbage collected, with React replacing them internally with the new effect callback function(s) for the current render.

when certain amount state changes exceeds the memory limit, would our app be in crisis?

No, because unused objects from prior renders will get garbage collected.

The following snippet will log Just got GC'd! when enough objects have piled up in memory and they get garbage collected:

const r = new FinalizationRegistry(() => {
  console.log('Just got GCd!');
});

const App = () => {
    const [someObj, setSomeObj] = React.useState({ num: 0 });
    setTimeout(() => {
        r.register(someObj);
        setSomeObj({ num: someObj.num + 1 });
    }, 100);
    return JSON.stringify(someObj);;
};

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>
0
votes

The argument passed to useState is the initial state much like setting state in constructor for a class component and isn't used to update the state on re-render

If you want to update state on prop change, make use of useEffect hook

React.useState does not reload state from props