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

Brian creates a custom hook that performs the task of being a reusable dropdown component, and replaces redundant code from the animal and breed dropdowns.

Get Unlimited Access Now

Transcript from the "Custom Hooks" Lesson

[00:00:00]
>> Brian Holt: Before we get to requesting against the API, I wanna show you how to do with something that's called a custom hook. So right now we've just been using useState all over the place, but if you notice HTML for animal, or this one here right animal and breed.

[00:00:18] These are almost the same thing, right, to the point that like, it'd be nice if we could have some sort of like reusable bit. That would do like a drop-down for us, and we didn't have to do all this song and circumstance. And we could maintain them together, so let's actually go do that.

[00:00:35] So make a new file here, and call it useDropdown.js.
>> Brian Holt: Okay, here you wanna import React from 'react'.
>> Brian Holt: And we're also gonna use useState.
>> Brian Holt: Okay, and then I'm gonna say const useDropdown, this is gonna be our hook that we're gonna create. And it's gonna take in a label, some sort of default state, and some sort of a list of options to put in there.

[00:01:16]
>> Brian Holt: Then down at the bottom we're going to export default useDropdown. So we're gonna say const state, useState, so we're gonna make this like a generic dropdown.
>> Brian Holt: So not useState but setState
>> Brian Holt: Equals useState, and the default state of this is going to be whatever they pass in, so default state.

[00:01:50]
>> Brian Holt: We're gonna get some sort of ID, so you just need it to be something unique, because we have to give things keys and such. So I'm gonna use template strings, so I'm gonna use backticks, backticks are the ones next to 1 on your keyboard. Then we'll say use-drop down-$ curly braces and then JavaScript expressions can go in here.

[00:02:15] So, I'm gonna say, label.replace, so take any spaces out of the string and also make it lowercase.
>> Brian Holt: So like if label here was something like Best Dogs Ever or something like that, right? What this would do is it would make this
>> Brian Holt: Look like that, right, that's what this would output there, right?

[00:02:47] Doesn't matter that it's readable, it just matters that it's unique.
>> Brian Holt: Okay, and then the component that we're gonna make is called a Dropdown, so const Dropdown equals an arrow function. And we're just gonna use that implicit return again with the parentheses, equals label htmlFor equals the ID.

[00:03:19]
>> Brian Holt: And then here, this is gonna have an ID, we need to put a label inside of that label which is coming in here from the parameters. And then we're gonna put a select inside of that.
>> Brian Holt: And we have to give that select an ID as well, so id= [id], value = state which we created up here, so state.

[00:03:49]
>> Brian Holt: OnChange, we're going to call e and we're gonna say to setState to be e.target.value. And then the same thing for blur, onBlur.
>> Brian Holt: And then we have to give it that disabled thing as well, disabled equals options.length triple = 0. Here we're gonna give it an option of all, which is gonna have no value, right?

[00:04:34] Which means it's going to have nothing selective when it's on all. And then here we're gonna say options.map and do the same thing with map. So this is gonna be some item in the array of some option, we'll stick with item. Use our implicit return with parentheses and say option key=[item], value=[item], and then item right there as well.

[00:05:24]
>> Brian Holt: Get my parentheses all matched up, here we go.
>> Brian Holt: So now we have this generic drop down component, right? That's gonna take in a label, some default state options and make a dropdown component. So now what we're going to return down here at the bottom, is we're gonna return the state, the Dropdown.

[00:05:54] And then we're also gonna return this setState function as well.
>> Brian Holt: Like that, and now we can use this just like we used a hook, because this is gonna give us the state. The Dropdown's gonna handle all of the setting and unsetting of the state, right? And then just in case as well for later, we're gonna return this setState function.

[00:06:19] So that we can programmatically update it, in addition to using the Dropdown. So I understand this is a little abstract, we've taken the animal Dropdown and the breed Dropdown. And then we've just formed it into this kind of generic Dropdown hook.
>> Brian Holt: Good so far? All right, so let's go ahead and go back to the search params.

[00:06:47]
>> Brian Holt: And what we're gonna do, instead of doing animal and setAnimal, what we're gonna do is we're gonna say const.
>> Brian Holt: First thing is you have to import up top, so Import useDropown from ./useDropdown. We still need breeds so we'll keep track of that, but now what we're gonna do is we're gonna say const [animal, animalDropdown].

[00:07:26] And we'll actually just leave it at that for now, = useDropDown, and we'll give it Animals the label.
>> Brian Holt: We'll give it dog as the default state, and we'll give it Animals as a list of options to choose from. Then for breeds we're gonna say const,
>> Brian Holt: Breed, BreedDropdown and we'll leave it at that for now equals useDropdown with "Breed" empty string as a default state, right?

[00:08:08] And breeds which again we'll handle this from the API here is just a second later. So now I have this animal Dropdown and this breed drop down, so rather than having all of this label stuff here for that. I'm gonna delete Animal and I'm gonna delete Breed.
>> Brian Holt: So now I just have the location one, which is different, we don't wanna make that generic right now.

[00:08:33] But what's cool is I just have an AnimalDropdown and a BreedDropdown.
>> Brian Holt: And that's pretty cool in my opinion, we've kinda taken out this logic, we extracted it out to this useDropdown hook. And now we just get these little AnimalDropdown, BreedDropddown, self contained dropdowns. So if I save this and I go back over to my code this all works exactly the same way now.

[00:09:05] But it's using this kind of shared generic class, or hook, as it were.
>> Brian Holt: And what's great about this is now I can write all sorts of unit tests,and I can use this all over the place. And I can kinda guarantee to my future self that this is a really good piece of code that I can reuse over and over and over again.

[00:09:32]
>> Brian Holt: Now we have a bunch of errors around unused variables, we will fix this momentarily, but you should expect to see that right now.