When State Changes

Here's a handler that changes the state and then prints it:

function handleLike() {
    setLikes(likes + 1);
    console.log(likes);
}

After the first click, the page shows ♥ 1, but the console says 0. After the second click, the page shows ♥ 2, and the console says 1. The console is always one behind. Is setLikes() slow?

No: it doesn't change likes at all. It can't, because likes is a constant of this render. setLikes(1) only tells React that likes will be 1 from now on, and React renders the component again once the handler has finished. That new call of App() has a new constant likes, which is 1. But the handler that's running belongs to the old render, where likes is 0, and for this handler it stays 0 until the end.

Think of each render as a snapshot. The JSX, the handlers and the state values in it are all from one moment, and nothing in a snapshot changes. Calling a setter asks React for a new snapshot.

When the handler needs the new value, compute it first, keep it in a constant, and use it for both:

function handleLike() {
    const newLikes = likes + 1;
    setLikes(newLikes);
    console.log(newLikes);
}

Now the console says 1 together with ♥ 1. The same goes for conditions: if (likes === 10) right after setLikes(likes + 1) checks the old value, so it's true one click later than you'd expect. Check newLikes instead.

Instructions

The handler prints the old number of likes. Make it print the new one, the number that the page shows: Likes: 1 after the first click.

When the likes reach 5, also print Night Trains has 5 likes!, once, with the click that makes it 5.

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

Back

5/13

Next