This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "getInitialState() and setState()" Lesson
[00:00:00]
>> Brian Holt: So, let's make React actually keep track of that state. So, the first thing we wanna do is we need to give it an initial state. So, above render put a function called getInitialState.
>> Brian Holt: I suppose something I didn't talk about with regards to ES6, the syntax of declaring functions, this is called enhanced object literal syntax.
[00:00:25] Most of us are used to seeing like that, right. But I told you, ES6 is about not writing function. So, they now allow you to write that just like this. Same thing, just need it a little bit shorter. Okay, so you have getInitialState and what we're gonna do here it's going to return the first state of search you wanna have.
[00:00:49] So we're gonna say, return an object with searchTerm of, I'm just gonna put a random string here, so you can kinda see how this propagates out. Eventually, this will just be empty string. But we're gonna say, this is the default string.
>> Brian Holt: Okay, so save that. So now, we have this bit of state that's being tracked on search, right?
[00:01:19] And we're just going to make input the value of input be this.state.searchTerm, right? So now, the value of input is always going to correlate to what's in searchTerm. And just for demonstration purposes, we'll change this back later, but I'm gonna make the h1 reflect it as well, this.state.searchTerm.
[00:01:50]
>> Brian Holt: Okay? So, if we save that,
>> Brian Holt: Come back over here. First of all, if you have your console open, it's gonna yell at you for a good reason, but it also says this is the default string. And if you come over here and say, this is the default string, now try and type in it.
[00:02:11] Congratulations, you broke the browser.
>> Brian Holt: This is another big point of frustration for new developers approaching React. Especially, if you're coming from something like Angular or Ember, where the two way data binding is free. It is not free in React and that is also by design. Because if you've ever had a debugging problem with two-way data binding, it is the worst because there's so much magic going on there.
[00:02:36] And at least for me, when there's problems with magic, it's really ungood, [LAUGH] to put it lightly.
>> Brian Holt: So, let's talk about why this doesn't change. Why specifically we broke an input. That's actually really hard to do it's hard to break inputs with JavaScript. So, every time I punch a key into my keyboard that fires off an event.
[00:03:06] And React is listening for all of these events. And every time it kicks off an event, React says, something happened. I'm gonna kick off a re-render and this is all for free. This is all stuff that React is just doing for you. So it says, cool, go ahead and re-render search.
[00:03:22] It goes through and it says, okay, I had this input and the value of this input is this.state.searchTerm, right? And that's this right here. When we have these events, what is modifying search term?
>> Brian Holt: Nothing, right? Nothing modifies it, so it just keeps staying the same. So, every time it kicks of a re-render, it just always gets re-rendered back to the way it was.
[00:03:47] Hence, it never changing, right? So, every time you type, nothing goes in there. So basically, you have to give it a pathway to modify that state. Make sense?
>> Speaker 2: Is it literally like capturing the event and just like not propagating it, just capturing it, so the browser doesn't get it?
[00:04:05]
>> Brian Holt: Yeah, I think, events don't escape react, so I don't believe you can listen above and catch those events. It's by design like if you're going to be using React, you should be using React, right? And you shouldn't be trying to play on the outside of and feed stuff into React cuz that's just gonna make things a lot worse than you want it to be.
[00:04:30]
>> Brian Holt: So, we have to give this input an on change listener. So, we're just gonna say, onChange. I'm gonna say this.handleSearchTermChange. There's nothing special about this particular method name. But I always call it that handlers, handle blah, blah, blah, right? For me, it's just a really useful way of knowing.
[00:04:59] Okay, this is a event handler.
>> Brian Holt: Okay, and then I'm going to create a method by the same name, handleSearchTermChange, that takes in an event.
>> Brian Holt: Okay, this event technically is a React synthetic DOM event, which is basically their imitation of an event. However, its API is precisely the same as the MDM normal browser event.
[00:05:30] So, you can just actually read the MDM and go by that. But I just didn't want anyone to be surprised by that. So, what I am going to do here is I'm gonna say, this.setState,
>> Brian Holt: ({searchTerm: event.target.value})
>> Brian Holt: So, event.target.value., this should probably look familiar to you if you've written any sort of direct DOM manipulation before, specifically with event listeners.
[00:06:08] This is just the API to pull out whatever was in the input.
>> Brian Holt: Okay? It's talking about this.setState, this is the gateway, the only gateway to modifying state in react. If you want to change something up here in state, the only way to do it is through the set state API.
[00:06:31] So, you just give it an API of it, of basically your delta. Your dif, the thing that you want to change. The reason why I say that, let's say if I have another piece of state here like, sort ascending, something like that. This does a shallow merge for you.
[00:06:48] Basically, object that assigned. In fact, it might literally use object data sign, so it will leave sort alone. You don't have to pass in the whole state. It's fine just give you the things that you want to change. The only thing is that it doesn't do a deep merge.
[00:07:03] So, if you have like deeply nested data, you do have to worry about that yourself. Okay, so setState, that's how that works. You don't need to sort there cuz we're not doing that.
>> Brian Holt: So, what setState will do is it will update the state object and then it will kick off another re-render and then you'll actually get these, the UI will reflect whatever is in the state.
[00:07:34] So, if we save that and refresh, now if you start messing around with this.
>> Brian Holt: All right, notice that this changes along with it.
>> Brian Holt: Right?
>> Brian Holt: Any questions about that?
>> Brian Holt: So, that's the thing to keep in mind is setState is the gatekeeper to modifying state. There is no other way to do it.
[00:08:20]
>> Brian Holt: There's no other way you should do it, I should say. [LAUGH] Always put like the asterisks at the end. I'll show you. You can do it this way. You can say this.state.searchTerm = event.target.value. There's no magic to what state is. It's literally just the object that you're keeping in state.
[00:08:42] They're not keeping that from you. The problem with this is no one's watching, right? No one's watching this.state for changes, so it doesn't know that anything changed, right? So, I modify this. It's not going to kick off a re-render. It did modify the state, but now the state and the UI are out of sync, which is a bad thing, right?
[00:09:01] So you say, well how do I fix it? You can say, this.forceUpdate.
>> Speaker 2: Question.
>> Brian Holt: Yeah.
>> Speaker 2: Is there any shortcut for doing a deep merge in such state? Like using previous state and do object assign with the previous state and then update the change?
>> Brian Holt: Yeah, that sounds pretty good to me.
[00:09:18] [LAUGH]
>> Speaker 2: [LAUGH] I think they're asking for a shortcut.
>> Brian Holt: There's no further shortcut to that.
>> Speaker 2: [LAUGH] Okay.
>> Brian Holt: So, this forceUpdate, this ends up being bad because this says, update right now. Something that's really nice React will do for you behind the scenes. Notice I had an event, which would normally kick off a re-render, but then I call setState right here, right?
[00:09:42] It's actually smart enough, it being react, is smart enough to batch that into one re-render. So basically, when you call setState, that's actually an asynchronous function that's going to schedule an update. An event, it's going to empty that buffer and into one setState, so that's only updating the bare minimum of things possible to keep your app performing.
[00:10:04] As soon as you call this.forceUpdate, it's just like a sledge hammer. So it's like, nope. Just update everything right now. So I would say, I'll be you a lot of React developers don't even know that this.forceUpdate exists. Because you don't ever need it. Really ever. The only time that you do, would ever use forceUpdate in a non bad way is if you had to integrate with jQuery or something like that or D3.
[00:10:30] Actually, D3 would be really a good example of that. Because you have D3, D3 needs to be a master of some of its own data. And then, it needs to tell React just like, hey, React I changed so much stuff and I need you to like re-render. So D3 will call back out React and say, force update.
[00:10:47] But integrating with other libraries is pretty much the only reason I ever use force update. So, don't do this just use setState. Use setState all the time, all over the place. It's the happy path just do that, but just note that force update is available to you if you need it.
[00:11:14]
>> Speaker 3: Are we gonna do any discussion of what actually happens during a re-render, like the way the diffing algorithm works?
>> Brian Holt: No.
>> Speaker 3: Okay.
>> Brian Holt: But that brings up a saline point. Notice like I actually have, I don't think I said the word virtual DOM at all today, right?
[00:11:33] Which when we have a conversation about React, that almost is one of the first things people brings up, it has the virtual DOM and my response to that is, who gives a shit, I don't care. React virtual DOM makes, it doesn't make React desirable it just makes it visible in my opinion and I thinks that's pretty good assertion to make, right.
[00:11:55] It doesn't really matter what React is doing underneath the hood, right? It just matter that it works and it's fast enough.
>> Speaker 4: So, let me ask you this if you ever run into a problem where you needed a deep understanding of that to debug it?
>> Brian Holt: Mm-mm.
>> Speaker 4: Never?
[00:12:09]
>> Brian Holt: I don't think so.
>> Speaker 4: That's impressive.
>> Brian Holt: Yeah, that's a bunch of stuff about the virtual DOM, I have no idea how it works. And it's about to totally change when they move to fiber, the fiber architecture.
>> Speaker 4: Cool.
>> Brian Holt: But this also brings up another good point of how to think about writing components.
[00:12:29] If you think about writing jQuery code, you basically have this kind of spaghetti code, that kind of just like, I click this. This changes this variable. And then I click this. And it just kind of gets this built up amount of state over time, right? And so, if you have to debug a problem with a jQuery spaghetti code app.
[00:12:46] You kind of have to think about your code and your state being modified over time, right? And this time element makes understanding what's happening in your app really, really, really difficult. It's probably, in my opinion, the most difficult part about debugging a non-React app is you have to worry about state over time.
[00:13:04] The way that React kinda sidesteps this successfully is it says, we're going to eliminate the time component from this. And basically you say, okay, given these props in this state, my app looks like this. So, instead of worrying about your app over time, you think given this snapshot, this is what this app looks like.
[00:13:26] Right, so given these sets of props, I have this search component.
>> Speaker 2: Question, if I don't want to update my search on every key press, would it be okay to use force update?
>> Brian Holt: If you don't want to update your state.
>> Speaker 2: On each key press.
>> Brian Holt: I'm gonna go with no.
[00:13:48] I don't think that's okay [LAUGH]. I think that's a bad idea.
>> Speaker 2: All right, next question. Is there a way to stop the re-render for debugging purposes?
>> Brian Holt: Not that I'm aware of nor do I think you want to.
>> Brian Holt: I mean, I guess, use the the debugger, right, use the browser debugger.
[00:14:10] That's probably what I would say if that's important to you.