In part 1, we discovered why useState
hook doesn't update immediately and how could we overcome that. You can read it here
What if it's a function?
On part one, we looked at a simple problem, but what if we need to deal with a function?
In this example, we will dive into a different problem.
What do we have?
Here we setup 3 useState
hooks, each has a different default value useState(NUMBER)
. When the button is pressed, they increment by 1, 2 and 3. After that, just to keep things simple, we output updated values via window.alert
.
function Multiply() {
// each has different default value
const [addOne, setAddOne] = useState(1);
const [addTwo, setAddTwo] = useState(2);
const [addThree, setAddThree] = useState(3);
function addValues() {
// if button is clicked, current value increases.
setAddOne(addOne + 1);
setAddTwo(addTwo + 2);
setAddThree(addThree + 3);
// alerting the user
window.alert(`
Here are the new numbers:
Add One: ${addOne}
Add Two: ${addTwo}
Add There: ${addThree}
`);
}
return (
<div>
<button onClick={addValues}>Add numbers</button>
</div>
);
}
Alright, imagine clicking on the button and seeing the alert. What numbers would we see?
If you read the part 1, you would know that, we will get 1, 2 and 3, Instead of 2, 4 and 6.
Our window.alert
is showing old values to the user. On this example, it not a big deal, the user can click one more time to get next values but it's always going to be one render behind. In a real world application, outputting old values as new can cause problems.
How can we fix that?
Here is the solution:
function addValues() {
// we don't need these anymore
//
// setAddTwo(addTwo + 2)
// setAddOne(addOne + 1)
// setAddThree(addThree + 3)
//
// above code is replaced with this
const nextOne = addOne + 1;
const nextTwo = addTwo + 2;
const nextThree = addThree + 3;
// we need to update our setters
setAddOne(nextOne);
setAddTwo(nextTwo);
setAddThree(nextThree);
// we don't use addOne, addTwo... anymore
// we need to replace them with nextOne... so on
window.alert(`
Here are the new numbers:
Add One: ${nextOne}
Add Two: ${nextTwo}
Add There: ${nextThree}
`);
}
On part 1, we declared a new value nextValue
inside the onClick event, on part 2, we did the same thing inside a function. Because we had multiple hooks to deal with at once.
Working principle is the same:
- We set our default values with
setState(NUMBER)
- We declare new variable,
nextValue
- On click, current value updates with another number, like
currentValue
+ 1, - We save the updated value to
nextValue
- We call the setter,
setValue
, with thenextValue
. - React renders the current value, not the previous render.
And that is pretty much it.