Check out a free preview of the full Complete Intro to React, v3 (feat. Redux, Router & Flow) course:
The "Managing State" Lesson is part of the full, Complete Intro to React, v3 (feat. Redux, Router & Flow) course featured in this preview video. Here's what you'd learn in this lesson:

Brian introduces how the state is managed in a React application. As data is changed inside a component, React has a controlled process of getting, storing, and modifying the current state. The first instance of a mutable state will be in the Search component where Brian adds an input field for the search term.

Get Unlimited Access Now

Transcript from the "Managing State" Lesson

[00:00:00]
>> Brian Holt: Let's go inside here and search and I want you to put a header and an h1 with the name of whatever you decided to call your video service and then input type= 'text' placeholder='Search', cool. Save that check it out got a nice little header up here at the top now, wouldn't it be nice if like all of your stuff just style itself like this right.

[00:00:41]
>> Brian Holt: That will be fun. You should be seeing this nice little fixed header at the top. So now we have this input right here. It doesn't really do anything particularly interesting. It just outputs and inputs to the header but, we have no access to this input anywhere in the header.

[00:01:04] So what we need now is we need React to keep track of whatever is in that input. Right now, we would refer to this as an untracked input.
>> Brian Holt: Okay? So React has this other ability that we have not yet used called state, right. So, I guess something that we didn't mention is if we go down here to ShowCard.

[00:01:30] We have this props.title, props.year, props.description. This data, this props object, is immutable. You cannot change it. If I say props to that poster equals something else, it's not gonna actually change it, right. In fact I think React will give you an error. Or in other words, don't change it.

[00:01:50] [LAUGH] So things that pass down from the parent to the child cannot be changed in any way, shape or form. It's totally up to the parent what to pass down, and the child just gets whatever it gets, right? [COUGH] So, that's useful. However, sometimes, like we need state.

[00:02:09] Like we need things that are stateful. So React has this other concept besides props called state. So the peculiar thing about state is a component can have its own state, right? Like if we have some sort of like, you know, if I click on Svideo and it goes bold or unbold, right, depending on if I click on it or not.

[00:02:30] This particular component can keep track with its own state, but only a component can modify its own state. So for example if search has, or ShowCard has state, the search can't modify a ShowCard state and vice versa. ShowCard can't modify search's state, right. They can only each modify their own state.

[00:02:53] So again if one of them has a problem you know that the problem lies right there with the state. Furthermore, let's say I gave ShowCard state, right? And if I have a problem with Atlanta state here, I can be assured that billions didn't cause it, right? It must live within Atlanta, so it can only out modify its own instance, right?

[00:03:15] So let's take a look what that actually looks like if you go here to search, I mean you wanna make search be able to have its own state. So far what we've been using what are called functional components it's often called stateless functional components, they are stateless functional components because as you see here, there's no mechanism to get the state.

[00:03:37] So we need to convert this to a different kind of component which is called an ES6 class component. So what we're gonna do here is we're just gonna do a little bit of changes. We're gonna say class Search extends.
>> Brian Holt: Component, and we're gonna import component up here.

[00:04:07]
>> Brian Holt: And, we're gonna remove that.
>> Brian Holt: Okay, and then this is going to be a render method.
>> Brian Holt: It's kind of awkward to get this going but nice thing again is that I don't have to format this, prettier's gonna do it for me momentarily. And behold, looks like this, okay, so I have class Search extends Component.

[00:04:50]
>> Brian Holt: I imported Component up here. You are equally welcome to say React.Component, and not import it up here. This is just how I prefer to do it.
>> Brian Holt: Okay, it's gonna give you a lint error for now, we're gonna fix that. Basically, what it's saying right now is, hey, you don't have any state, this should be a stateless functional component.

[00:05:13]
>> Brian Holt: But we're gonna give it state here in just a second.
>> Brian Holt: So ES6 classes. Classes came with ES6. Much to the joy of Java developers everywhere [LAUGH]. Just kidding. I like to prod Java developers. Keep in mind that these, they're pseudo classes in the sense that these are not true classical inheritance.

[00:05:40] So don't treat them like Java classes. These are still prototype or inheritance just like it's always been in JavaScript. This is just a different way to write prototype or inheritance. So definitely keep that in mind. Okay? One thing about React component classes is that they must have a render method.

[00:06:01] A 100% of the time without exception must have a render method. Okay? So just keep that in mind, and the render method must return markup. That's really the only hard requirements of React components, everything else is kind of optional, okay?
>> Speaker 2: And the render method has to return markup?

[00:06:21]
>> Brian Holt: Uh-hm.
>> Brian Holt: Yep, yep, yep. Just like those stateless functional components, they also must return markup, right. It's the same kind of way. So you can think of those function bodies of the stateless functional components as being the same as render.
>> Brian Holt: Okay, so now we have that.

[00:06:48] We've converted this to an ES6 class.
>> Brian Holt: So yeah, ES6 lint is yelling at us, we're gonna fix that momentarily.
>> Brian Holt: So what we're gonna do here is we're gonna make a constructor. And a constructor takes in props, and then it passes props up.
>> Brian Holt: This is kind of annoying about ES6 classes.

[00:07:21] You just have to do this. This is just boilerplate that you have to do it this way. It takes in props and you have to pass it up. Then here we're going to say this.state. We're initializing our state here in the constructor. And we're going to keep track of the search term, which is going to be, this is some sort of debug statement.

[00:07:51]
>> Brian Holt: Eventually we're gonna make this just an empty string to be initialized with but, I want to put this debug statement there so, you can kind of see how we're using it. Okay? So, now we have some state for search.
>> Brian Holt: So what I want you to do is I want you to come in here and on the input say value ={this.state.searchTerm}

[00:08:29]
>> Brian Holt: Okay, so you should be able to save that, and come back over to your browser and you should see here the value of this is now tied to whatever the initial value of state was, right? Now I want you to try and type in there.
>> Brian Holt: I'm typing, I promise.

[00:08:53] I'm not just making noises. We broke it, right? It doesn't work.
>> Speaker 2: Locked me out.
>> Brian Holt: [LAUGH] So, what happened? We broke the browser. It's actually pretty hard to do, right? Typically breaking an input like this takes work. [LAUGH]. So let's evaluate what's actually happening here. So I press a key, right?

[00:09:20] That fires off an event. That event is caught by React. And then Reacts says, an event happened, right? I'm gonna kick off a re-render. So it re-renders everything and then finds the diff of between what was there and what you're trying to put there now, right? So in this particular case, if I type a letter, and then it re-renders and it goes back to re-render this value right here, what is this.state.searchTerm?

[00:09:48] But still this is some sort of debug statement right and as soon as I press that key nothing is modifying that right? So every time I kick off an event you still end up with that same string, alright? Hence, that's why it never changes, right? Because whenever we kick-off those events, nothing goes back and modifies its estate.

[00:10:08] So it's always gonna re-render what it has. Does it make sense? So now we need to de-break that. So we need to get an onChange handler. So onChange equals this.handleSearchTermChange. And we'll create a method called handleSearchTermChange. The text in an event calls this.setState and searchTerm which is going to be event.target.value.

[00:10:52] So, now we have this method here. HandleSearchTermChange which is going to be called every time a change event happens on this input, right? And in turn it's gonna call this.setState, which is a way that you change state. So again, it's do not do this.state.searchTerm = 'blah' right? Don't do that.

[00:11:17] The reason being is, this will work, this actually will modify the state. React doesn't put any safeguards in front of you. The problem is, if you do that, React doesn't know something changed. It's not observing for those sorts of changes. You need to let React know, hey React I called set state, now you need to kick off another re-render, right, so that's how that happens.

[00:11:41] So that's why we call this.set state, this is just a way that we let React know, hey I'm updating this, you need to kick off a re-render.
>> Brian Holt: It's actually, I'm simplifying there. To be honest with you, it is actually batching your changes, so you can call setState a bunch of times in a row and it'll only kick off one re-render.

[00:12:00] So you're kind of like opting into that optimization path by using setState. Or in other words, do not modify state directly, that's the take a way here, use setState. So if I save this, still not quite there right? This still doesn't actually work. If you go back here and refresh and I type in here, you're gonna get all sorts of error messages.

[00:12:27] It says you can't read setState of undefined. This is new as well. This finally got long enough that preview said, I'm gonna wrap this. So while this looks weird for HTML to be written this way, this is very normal to see React written this way. Once you start getting these really long HTML elements, it's just easier to see it on multiple lines.

[00:12:46] So that's how that happened. Okay. So here, handleSearchTerm. This get's called on every event, right. Where is this event handler called? The answer is I don't know, but the answer is not here, right. It's not getting called within this context. So what is this, wherever handleSearchTerm is being called, again, I don't know but it's not search and it needs to be search, right?

[00:13:17] But because we're calling this stat set state on search we wanna modify that instance of search. So in order words we need to bind the context to be the correct context. There's several ways to do this, I will show you the bad way, which inevitably you'll see somebody write it this way because it's the lazy way of writing it.

[00:13:38] I could totally put .bind(this)}. I'll save this, I'm sure lint is going to yell at me. JS prompt should not use .bind, good job. But it will work right. Now this works and the stays being set correctly. Why is this bad, this is bad because if you remember I was telling you rendering is called a lot right, its get called every single time that an event gets kicked off to make sure something change or something didn't changed,

[00:14:13]
>> Brian Holt: What happens when I call .bind? It's creating a new function every single time render gets called. Which, functions are cheap but they certainly are not free, right? And particularly binds, bind is a pretty expensive one. Recent versions of Chrome are a lot better, but if you're more than two or three versions old of Chrome, or pretty much any other browser, it's really expensive.

[00:14:37] So in other words, this is bad, do not do it. And if you see your colleagues do it, just throw something at them, right. So, that one is out.
>> Brian Holt: So, our answer is here. We're gonna say this.handleSearchTermChange = this.handleSearchTermChange.bind(this).
>> Brian Holt: This will happen once in the constructor and then it's forever working.

[00:15:07] So this looks super awkward, right? But now any time handle search term change gets called, we are guaranteed it's going to be in the right context. So again, if we come in here, now this works again, and we're not getting any errors.
>> Brian Holt: So you'll see this a lot.

[00:15:35] This is valid ES6 today, everything works. This is the way, for example, for a long time at Netflix, I was writing it this way.
>> Speaker 3: Supposed an arrow function is just as expensive as using bind?
>> Brian Holt: Yeah. If you're creating an arrow function inside of here, yeah it is.