Check out a free preview of the full Complete Intro to React, v8 course
The "useState Hook" Lesson is part of the full, Complete Intro to React, v8 course featured in this preview video. Here's what you'd learn in this lesson:
Brian demonstrates creating a SearchParams component with a location search form utilizing the useState hook, which allows the input to update the location's state. Placing hooks inside if statements or loops will cause bugs that involve useState returning the wrong state.
Transcript from the "useState Hook" Lesson
[00:00:00]
>> So we you can now go to 03-JSX for the milestone if you've fallen behind and you didn't wanna copy all that ES lint profile so feel free to go copy that. And we are gonna get into, Hooks, I want you to create a new file here and we're gonna call it SearchParams.jsx.
[00:00:23]
We're actually gonna start getting into really building our application. So just to kind of set your expectation here, we're gonna build an application where you can search an API for animals to adopt. It's a fake API that's hosted by Frontend Masters, so it's one that we can control and make sure that it doesn't ever go down.
[00:00:43]
But eventually I'm gonna show you at the end, if you wanna go hook it up to like a real API. And actually look at real pets to adopt, you can use the pet finder API to do just that. So, let's make a component here, we're gonna call it SearchParams.
[00:01:00]
And it's gonna be a function, we're gonna have a location. Feel free to put wherever you want in this location. This is all very United States centric, so apologies for that but that's just the API that we have. So I'm gonna put Seattle, WA, but feel free to put Minneapolis, Minnesota, or Chicago, Illinois, or whatever you want there, up to you.
[00:01:25]
And then under that we're going to return. I put parentheses here so I can go down to the next line. If you put parenthesis here and just go to the next line, it's going to think that the line has ended like that, right? And it's not gonna do anything underneath that.
[00:01:41]
So you need parentheses to tell JavaScript, I'm going to the next line. That's where the parentheses comes from. Okay, and then I wanna give it a class, like a CSS class, right? There's a kind of a weird restriction here in JavaScript. Class is a reserved word in JavaScript, right?
[00:02:03]
So if I say class Thing, right, that's what class means here. So I can't just call this class. So you need to call it className. To be totally fair, they didn't make this up, it's actually the name of the JavaScript API for it. Just to prove my point here, if I say inspect here, x =$0.
[00:02:29]
So now I have this span here, right, the span right there. What if I wanted to get the className out of that? Well, if I do x., className, that'll actually give me back the name of the class from it. So that's where the class name comes from. It comes from the name of the JavaScript API.
[00:02:53]
Some people get really upset by that, I'm just used to it. So Stockholm Syndrome, I suppose. Okay, search-params, And then we're gonna give it a form, and then we're gonna give it a label, I'm gonna give one to give it a label for something, right? Again, for is a reserved word, right, for for loops, you can get rid of class thing here, by the way.
[00:03:25]
So what do we have to call it instead of for it It's called htmlFor. So I think those are the two primary ones that you're gonna run into issues with, everything else, for the most part, just works. So htmlFor "Location", Inside of that, we're gonna give it a location.
[00:03:51]
As in the word location, and then we're getting input of id=, "Location" value="location" placeholder= "location" location, location, location. Okay, under that we'll give it a button. There'll be a submit button for the whole form. Okay, and then export default, SearchParams. So, let's talk about a couple of things here.
[00:04:37]
One, this is wrong and broken and I know and I'm gonna show you why here in just a second. So we have this variable here called location this could be anywhere that you're searching for a pet, right? You wanna limit it down to Salt Lake City to find your your pet or something like that.
[00:04:53]
So I have this variable here that holds the location of where I wanna search for. I want that to be the value of this input here. So what's the difference between putting curly braces here and putting quotes here. If I have the value here as quotes, this is literally going to put this string in there of location, right?
[00:05:14]
But I don't want it to be literally the string location, I want it to be whatever is inside the variable location. That is what the curly braces do here. If you put curly braces you're saying, hey, here's a JavaScript expression right? So this JavaScript expression is just location but this could be like location.twoUpperCase or something like that right?
[00:05:36]
An expression it's anything that can be on the right side of an equal sign right? So anything that can be on the right side of this can go in here, right? So .toLowerCase, right, or something like that, right? Anything that's a valid JavaScript expression can go here. For now, I just want the variable.
[00:05:59]
So that's that. And then now, I wanna use this in App.jsx. So pop over to App.jsx. You can delete the pet import and just import SearchParams, from SearchParams. Another fun trick I'll just show you really quick. So if I'm here in App.jsx, let's just say I didn't import this up here.
[00:06:27]
You can actually just start writing the thing that you wanna import. So I'm gonna put SearchParams, right this. Notice I don't have it imported at the top. If I just click on this, notice that it just automatically goes like okay, well, you're trying to import that, right? And that works, okay.
[00:06:46]
Okay and now I had this SearchParams component being rendered here from SearchParams. Okay, now if I go over here, go back to my Adopt Me, I'll make sure your server is running. I don't think mine is npm run dev tf. There we go, refresh. What do we got here?
[00:07:13]
Yeah, that is something that we did not fix. App.jsx create route from react-dom/client, I believe, right? You need to import create route from react-dom/client, which is client side browser side, right, cuz there's also server side rendering stuff here. So they separate them into different packages, okay? And then here in app, you have to have a return here, or else if nothing's getting returned, it's just getting declared and never used, just so that's what we fixed.
[00:07:48]
So refresh here. You will have an error in your console, that's okay, we'll take care of it momentarily. But let's talk for a second about our input here. How does React work? How does React know when to re render? Because basically with the way that this component works here in SearchParams.jsx is that, it'll continually re-render this a bunch of times.
[00:08:15]
These render functions get run a lot, which means that they need to be fairly fast. Every time when an event happens in JavaScript it re-renders everything, top to bottom. So, you have to ask yourself, if I start typing in this input and I press the button, and a top level dump event happens and React says cool, the user did something, something probably changed let me re-render my self, yeah?
[00:08:44]
So if I type on this input and I, let's say I type the letter R, right, so you would expect it to say Seattle WAr, right? If I typed it a lowercase r there, well, what happens? If I type in it a re-render cycle happens. What is location?
[00:09:05]
>> Seattle, Washington.
>> Seattle, Washington with no r, right? Because nothing's changing this right? So if I go back over here and I'm typing in I am literally hitting the letter r right now, nothing is happening. Because, nothing ever changes location. So no matter what, I keep typing in here, nothing is happening because the event is happening and React is re-rendering itself and nothing is updating that location.
[00:09:39]
That's a problem, right, we have successfully broken the browser. So we need to be a bit more explicit about this controlled input, right? You can see here it's saying, hey, you provided a value prop without an on change. So actually React is kind of ahead of you here and it's, I know you broke this so you should go fix this.
[00:10:01]
So let's make something that can actually change. We need something called a hook. So I'm gonna say up here I'm going to import a thing called a hook from React. So I'm gonna import, use state from React. And I'm gonna say const Location and setLocation =useState and then whatever you want the default state to be.
[00:10:33]
So that that can be Seattle, WA or whatever you want. For now, let's just do that and see what happens. And so now I have this thing called Location which is coming in from Seattle, Washington. All I need to tell it what to do whenever something changes on this input.
[00:10:49]
So I'm gonna say onChange, And I'm gonna give it a function. So it's gonna take in an event and then it's going to setLocation to be e.target, target.value. This setLocation function is what you call, To let it know, hey something changed go update yourself. Okay, so now if we go back over here it successfully updates, we successfully unbroke it.
[00:11:46]
Now, I'm gonna set this to be empty string cuz by default I don't wanna search in Seattle, I wanna search everywhere, right? So now if I go back over here, by default it's empty, right? So let's talk a little bit more about these render functions. These render functions are meant to be totally stateless, right?
[00:12:04]
So if I have some sort of counter here, this is a terrible idea, so don't do this in production that counter= 0. And every time this runs I say counter++ and then we'll just output an H2 here of the counter. Right, this render function is getting called so many times.
[00:12:33]
Every time obviously I'm clicking on it, will click a Submit, I don't know, other stuff, right? So these kinds of they're called side effects, right? If we're using the dumb functional programming computer science stuff, you're not allowed to have side effects inside of your render functions, right? So, your render functions need to be fast and they need to be stateless, right?
[00:12:59]
When I say stateless, it means that they're not modifying global and being stateless. This counter here is an exact counter example to what I'm telling you, right, don't do stuff like this. And given that. Cool, so the way that you have state inside of a function, is you use these hooks.
[00:13:25]
So these hooks are then passed into React and then React gives them back to you. So that's what this location is it gives you some piece of state that you're allowed to keep track of internally to a React application. In this case, we're keeping track of the location, which can change, depending on how the user updates their form, yeah?
[00:13:47]
And then you can add as many pieces of these like hooks states inside of your application. Couple of rules about hooks, they have to be called every single time in the same order. Which is to say, don't do things like if thing you can't do this. You can't have conditional creation of hooks, they have to be created every single time in the same order.
[00:14:17]
Cuz the way that React is keeping track this is, this component calls these pieces of state in this order. So if you're putting ifs or for loops or things like that in there, you might be calling them out of order, and therefore you might get your state back out of order, right?
[00:14:34]
So don't do that.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops