Reputation: 3165
As per React official documentation, if a component new state is computed using the previous state, one can pass a function to setState. The function will receive the previous value, and return an updated value.
Consider the following code snippet example:
const [counter, setCounter] = useState(0);
const btnClick = useCallback(() => setCounter(counter+1), [counter]); //(1)
const btnClick = useCallback(() => setCounter(previous => previous+1), []);//(2)
btnClick is passed as a callback function for the 'onClick' event of a rendered button.
In (1), the btnClick function reference is updated each time the counter
state variable is modified.
In (2), the btnClick function reference is created during the first render cycle and is cached for the rest of the component lifetime; at this level, the state update function will receive the previous state value and return an updated value.
At this level, I have 2 questions:
1- As a good practice, should I opt for (1) or (2)? And are there any advantages for using (1) instead of (2)?
2- Does (2) apply to both primitive and reference types? (check below, I switched the state from being an Integer to an Object)
const [counter, setCounter] = useState({cntr:1});
const btnClick = useCallback(() => setCounter({...counter,cntr:counter.cntr+1}), [counter]); //(1)
const btnClick = useCallback(() => setCounter(previous => return {...previous ,cntr:previous.cntr+1}), []);//(2)
Does "previous" in (2) still reference the previous state value or does it refer to a stale state that was cached during the component first render cycle?
Your help is appreciated.
Upvotes: 3
Views: 600
Reputation: 354
So, it is a deep question, let's try to explain how it works.
useCallback
just promise you that btnClick
will not reinitialize. This does not related to useState and body of function at all.setValue(1);
setValue(2);
setValue(3);
It does not mean react will update the state three times. React can combine it to one update and set just last value.
const myFunc = (oldValue) => ({})
useValue(myFunc)
it means that react sees you pass function then all useValue
will be called immediately and after useValue(myFunc)
will be called.
Developers need it to work with last data which is placed in the state.
Does "previous" in (2) still reference the previous state value or does it refer to a stale state that was cached during the component first render cycle?
So, as a result of the question previous
in setState
will be recent value from state.
Upvotes: 2