Check out a free preview of the full Complete Intro to React, v6 course:
The "Animal & Breed Selector Hooks" Lesson is part of the full, Complete Intro to React, v6 course featured in this preview video. Here's what you'd learn in this lesson:

Brian live codes the selector for animal type and breed using the useState hook and demonstrates what it looks like when ESLint throws an accessibility error. The breed selector will utilize an API call to generate options which will be covered in the useEffect & Fetching API Data segment.

Get Unlimited Access Now

Transcript from the "Animal & Breed Selector Hooks" Lesson

[00:00:00]
>> Let's go make like an animal drop down so we can choose what kind of animal we wanna search for in our pet adoption app. So first, we're just gonna say const ANIMALS. And this is a list of animals that we can choose from. Bird, cat, dog, rabbit, reptile.

[00:00:24] I put it all in capital case you know that like this is just a constant and never changes. This is just the name of the animals that we can choose from. And then underneath the label here, this one and write another label. This is htmlfor animal, Animal. And this is gonna be a select underneath it.

[00:01:03] Okay, that's gonna have an id of animal And the value is equal to, Animal And the onChange, We're going to set to e, Set animal e.target.value. And then we'll fix this in a second, I'm gonna cause intentionally an accessibility error, so you see what those look like. And that'll be the end of the select and then we'll close the label down there.

[00:01:54] Okay, so the first thing it's gonna give me an error here is like, hey, onChange isn't quite enough. And to be truly accessible, you also have to worry about blur because if someone tabs down there, it may not necessarily trigger an onChange and it varies from browser to browser.

[00:02:10] So that's why I quite like that accessibility one that we installed the furiously and it will remind you of stuff like this that for example, I didn't necessarily know until this were warned me about it. So we'll just add the same event handler here for onblur. And now that gets rid of that one, we haven't made this hook yet.

[00:02:32] So let's go to find that hook. It's gonna look exactly like this one. Const animal, seAnimal equals useState and, you know, whatever default one you want, you could put dog here. I'm just gonna leave it blank so that it's as if someone hasn't selected an animal at first Okay, the first thing we wanna set is there should be an option, For someone that hasn't selected anything, or because of this JSX, you can actually just do that.

[00:03:11] So you can have self closing tags for things that aren't necessarily self closing tags and JSX that doesn't care. Okay, and then here, we wanna do an option for each one of these animals. So we wanna loop over and create a react component for each one of those and I would rather not code that by hand.

[00:03:30] So what we can do here, is we can actually use these curly braces to put a JavaScript expression in here. And I'm gonna say, ANIMALS.map. Cuz animals is just an array of strings and .map is just gonna go over every element in that particular array. And it's gonna create a new array with everything that I returned from it.

[00:03:55] Okay, so animal.map, and then I'm gonna have animal. And now I have a new function here. So I could say return, blur, right? It's actually kind of a fun thing you can do. If I don't put any curly braces and I instead put parentheses here, it's going to return whatever I put here.

[00:04:17] So I'm going to return an option, Where value equals animal. And I'm gonna put animal in here as well. Now, it's gonna say here, hey, you did a map here. And you didn't put a key. Remember that error that we saw earlier in the browser about it wants to be able to have a key for each one of these?

[00:04:45] So let's go ahead and put a key in there as well. Key, and you need to put some unique string per option, right? This could be like an id, this could be something like that. What we do have is we have animal and we know that each animal is unique.

[00:04:58] The only thing that we care about is that it's unique. So if I reorganized dog and rabbit and I swapped him for whatever reason, it would know is like okay, those swapped in, I'm just gonna move those options. So you can just put key as animal ,typically, you don't wanna put it as index, right?

[00:05:19] The index is tied to, if I move index zero to index one and index one to index zero, their indexes will have changed, right? And they're not actually tied because the thing would still be an index zero and it's still be at index one and wouldn't move necessarily with that.

[00:05:36] So that's why indexes is not a good thing to have for key. Okay. So, option, option. And that works, I think this should work now. So let's go take a look. So we have Seattle, WA here. And now we have a drop down of bird, cat, dog, rabbit and reptile.

[00:06:04] If I select dog, it selects dog. Good stuff right? Any questions about that? I know this can look a little strange if you're not used to coding like this. But just keep in mind, this is basically a return statement right here just implicitly. In fact, that's actually literally what it is.

[00:06:28] If I did this, it actually would just work. Right this return, I'd have to go figure out the correct curly braces and whatever, right, but by leaving out that's what it looks like.
>> On line 29 you have given self closing the option tag, but on line 31 and 34 you have closed the actual tag, so is it valid?

[00:06:54]
>> This isn't technically valid Java, HTML. The way you write that HTML would look like that. And you can actually leave it like that if that makes you feel better. But this is basically like, value equals blur and with nothing in there, if we go look over here, it's actually this top one right here, right?

[00:07:14] It's the empty one that represents they haven't selected any animal, right. These are the ones, like this represents dog with value of dog. That makes sense.
>> Yep.
>> Cool, that might even be clear, so feel free to leave it like that. But I was doing this the lazy way of doing it.

[00:07:34]
>> I have a question about the key. So for the animals, what if it's a duplicate value? So if you have two dogs, would it be able to distinguish as well between those two?
>> Nope, it must be unique, right? So if I put in a dog here just to show you how much it gets upset about that.

[00:07:51] If you look here in the encounter two children with the same key and it just drops them so I think actually it only just gets upset. It used to not even render them but it'll be upset the whole time like you gave me multiplicate, I trusted you and you gave me the same key.

[00:08:07]
>> So that's why I'm confused. So why if it's a duplicate thing, would it be better to use an index because you set the index if the index changes, then it's going to cause an issue. So how would you deal with like an array that might contain a duplicate value?

[00:08:27]
>> So if they're truly duplicate items and they have no distinguishing features between the two of them, then you would probably use the index.
>> Okay.
>> Like that's the absolute last resort if is you would use the index but hopefully they have an id or something like that that you could use.

[00:08:45]
>> So using the index is like the worst case like it's your last resort type of thing to fall back to if there's nothing else to use as the key?
>> Yeah, you're basically at that point just doing it to make Eastland's shut up right? Because you'll get no benefit from giving it index cuz basically what you're saying is if anything ever re renders destroy it.

[00:09:09]
>> How declared the animals array outside of the component, but you are using it inside. Are we mutating the state?
>> No, in fact it would, you would wanna be careful to not, I mean I guess you could come up here and say object.freeze. If you really want it to be super guarded against that and now you can see here it's actually a read only now.

[00:09:35] But here when you do map it doesn't modify the array it creates a new one. That makes sense?
>> Yeah.
>> I mean, this is unnecessary. You don't have to do the object.freeze, but if you want it to be triple secure that it never got modified to tell you to do it.

[00:09:54] Let's make another one of these. So we're gonna create another hook here, but we're gonna do it for breed. And, For now, let's just make an empty array of breeds. So we're gonna say const breeds = empty array. Then we'll come back to this cuz we're gonna grab the breeds from the API.

[00:10:25] Here, what I'm gonna do is I'm actually just gonna copy this whole label and paste it. And we'll just change everywhere says animal to breed. So set breed. Breed, breed, breed. And then here instead of animals we're gonna say, breed or breeds rather. And then here now for places where it says animal, we're gonna say breed.

[00:11:04] So breed, breed and breed. Cuz we want it to function relatively the same way. One of the VS code tricks that I just use there for those that are using VS code. So if I highlight breed here and notice it's highlighted. If I hit Command D, and I think it's Ctrl+D as well, in Windows, it'll select the next instance of that exact match.

[00:11:26] So you can see here now I've matched both of those. And then Ctrl + D, Ctrl + D, again, and now I've select all four, and I can put whatever here it'll type in all four places at once. I use that all the time. So it's a useful trick if you're not using it already.

[00:11:48] Okay, so now if we look over here, we'll have a breed selector nothing is in it. It it's kind of what we expect. Well, there's one option, it's the empty option.