This course has been updated! We now recommend you take the State Management with Redux & MobX course.

Check out a free preview of the full Advanced State Management in React (feat. Redux and MobX) course:
The "React Component State Quiz" Lesson is part of the full, Advanced State Management in React (feat. Redux and MobX) course featured in this preview video. Here's what you'd learn in this lesson:

Steve uses a quiz to highlight common issues with using component state in React and how to fix them with passing in a function as an argument to this.setState.

Get Unlimited Access Now

Transcript from the "React Component State Quiz" Lesson

>> Steve Kinney: All right, it's time for a pop quiz. So here is, again, a simple version that we just kind of type. This is using the slightly older syntax, just in case it didn't wash over us completely yet. So we have a state that's gonna start at zero. Inside some function we're gonna call this.setState three times in that function, incrementing it by one.

[00:00:27] And then immediately in that same function we are going to console.log it, right? So the way we play this game is we all take a mental note and we try to think deep and maybe write it down. Maybe just tattoo it on yourself. What will the console log for this.state.count be?

[00:00:46] Anyone have any guesses?
>> Speaker 2: Zero.
>> Steve Kinney: We got a zero, we got a three. Any other guesses? Those are pretty solid. Correct answer is zero. And the reason for that is that this.setState is almost always asynchronous. For our purposes, let's just say that it's always asynchronous, right? So all three of those will not happen right then.

[00:01:14] The reason for this is that React is trying to avoid unnecessary re-renders. It's like, the state has changed. Let me collect all of these state changes and then I will figure out, I'll do the virtual dom, and I'll figure out what I'm supposed to do, right? So in this case, we can increment it.

[00:01:34] This is again a simple version of our counter. All right, let's play this game. We'll call increment three times right here. What is this going to be the next time that it renders?
>> Speaker 2: Three.
>> Steve Kinney: I got a three guess. All right, we just called it three times in there.

[00:02:00] All right, we're gonna guess next time it renders, what are we gonna show on the page as the count? You can also try this in the code. You have the example, too, so we can take it for a spin. But so the answer is 1, right? So we took this.stateaccount and we said it was plus 1, three times, right?

[00:02:20] But in that case we're just queueing up all the state changes and React is gonna batch them up. So it got the message three times, but the new state of count was the current count plus one. And then we told it again it's the current count plus one.

[00:02:35] We told it a third time, it's the current count plus one. But guess what, that still is. Zero plus one is still one, even if we say it three times. Right, so it queues all of them up and tries to figure them out together. Cool, so in this case, effectively what's happening, if you've ever used Object.assign, we'll actually use a different text for a little bit later, is that it grabbed one of those objects and merged them together, right?

[00:03:03] So at this point, it just got the same message three times. The last one won in this case, so we end up with just one in this case. And for most of my career using React, I was passing an object and that seemed very cool. But there's actually other interfaces that you can use with this .setState.

[00:03:25] So here's a fun fact. Did you know that you can pass in a function as the argument instead of an object? And that's gonna behave a little bit differently. So here, instead of passing in an object, we're gonna pass in a function that's gonna take the current state and it's going to return a new object that is state.count + 1.

[00:03:48] So we call that three times, and does anyone have any guesses what we'll see rendered this time?
>> Steve Kinney: Three. We use the function rather than merge a bunch of objects which is what it does when it sees objects, it grabs the functions and it plays through them. One, then two, then three.

[00:04:12] It plays through each function that it receives. So we'll get state.count plus 1. Then we'll get to two. Then we'll get to three before we render it. So it behaves slightly differently and more the way since three was our guess when we saw the object before, behaves more the way that we expected the original syntax to behave.

[00:04:29] So it plays through each one of them. And this actually gives us some interesting programmatic control. They're learned about off of the Twitters, some Dan Abramov, which is you can actually pull those functions out. So just say we're using increment all over the place. You could pull those functions out and pass them in, right?

[00:04:48] And if we see the state, it'll increment it. They're not tied to that given class anymore. Another thing that I'd like to do with it is I can now look at the state in this case and I can have some of my programmatic logic here. So if I want the counter to never go back at five, as I'm playing through all of those functions that are trying to change the state, I can actually look at what the state is after the last one that played.

[00:05:09] So if I have many of them happening at once. And arguably, you can be like, I shouldn't have many of them at once. But things happen in large applications that we don't want to talk about in front of new friends. So this gives you the ability to see what the state is as it plays through this one.

[00:05:25] And kinda gives you a little more control, and again, is helping with strange edge cases. There's one other thing we can do with this .setState, is it turns out it takes a second argument. And that second argument is a callback function. So we can either pass in an object or a function that will mutate the state, and then we can pass a second argument that it will call once it has done that state change.

[00:05:52] So why would you use this? I actually use it a lot, so we have in the email editor we have a color picker. And one of the things that we do in there is we save the most recent colors to local storage, right? So I use the callback in this case.

[00:06:07] They have picked a new color. I wanna have the recent colors. I'm saving it to local storage every time it changes, right? I could try to do this but we want to have it after the state has changed, right? If something happens, I don't necessarily wanna save that, especially if I'm saving to local storage.

[00:06:22] And if it's because of a bug that I had where it wasn't a valid color, or the function blew up for some reason, I personally would rather not save that to local storage and try to rehydrate it forever and ever and ever and ever, because support will hate me.

[00:06:33] And like my sole job as an engineer is to not have support hate me. Or not have them come up to my desk, right? They're very nice but it usually means that my team did something wrong.