Custom Hooks
Custom hooks are arguably the most important addition of all the hooks released with React 16.8.0. Explore how custom hooks can dramatically simplify sharing code between components.
Custom hooks#
Unlike all the other hooks we've covered so far, which are actual hooks (useState
, useEffect
, etc.), custom hooks are simply: the ability to extract component logic into reusable functions. Which is a huge upgrade to how React works.
Remember in the introductory lesson when we talked about some of the biggest reasons that hooks happened? One of them was don't repeat yourself (DRY) in code and avoid having to duplicate it across various components or even across lifecycle methods within the same component.
Custom hooks make that possible. Up to now, React has had two popular ways to share stateful logic between components: render props and higher-order components. We will now look at how hooks solve many of the same problems without forcing you to add more components to the tree.
The moment you realize two components need the same piece of code, you've identified a potential use case for a custom hook. Or, if you want to clean up an especially large, complex component and modularize some of its functions, custom hooks could be your new solution.
You can write custom hooks that cover a wide range of use cases like:
Form handling
Animations
Declarative subscriptions
Timers
And probably many more I haven’t even considered — the sky is the limit!
The best part? Custom hooks use the hooks we've been talking about in this whole module. They just group a bunch of hooks together inside one wrapper, and you've got a brand new custom hook to drop into whatever component you need.
This lesson will teach you exactly what a custom hook can look like and how it can be used inside of another React component.
Sample custom hook: Close modal on click outside#
Here's an example of a custom hook you might want to use in your React application. Let's say your site has a number of modals that pop up from time to time. Perhaps, in addition to explicitly dismissing them via a Close button, you'd like them to dismiss whenever a user clicks outside of the modal's body as well.
While you could certainly write this code and tie it to a particular modal, if you want to apply this behavior to more than one modal (or you want the same sort of functionality with dropdown menus or tooltips), you'd be duplicating code. Therefore, this seems like a perfect opportunity to write a custom hook encapsulating that logic.
Let's talk about a few basics to keep in mind about custom hooks, and then we'll get to the meat of the hook itself.
How do custom hooks work?#
First of all, I want to reiterate a custom hook is a JavaScript function whose name starts with "use" and that may call other hooks.
The rest of the rules of hooks still apply to custom hooks, though: hooks must be called in the same order each time, they can only be used in functional components, etc.
Unlike a React component, though, a custom hook doesn’t need to have a specific signature. We decide what it takes as arguments and what, if anything, it should return. In other words, a custom hook is just like a normal function.
The major difference is in its naming: custom hooks should always start with use
so you can easily tell it's a custom hook.
Custom hook naming best practice
It's considered a best practice to name any custom hooks you may be creating as
useXyz
. For instance, this example hasuseOnClickOutside
, but you might also haveuseFetchData
oruseOnScreen
or whatever. Just try to name your hooksuseSomething
.
Pass information between hooks#
Since hooks are just functions, we can pass info between them just like we do with all the other hooks (which you'll see in our code example soon).
Each time the state being passed to the hook updates, the custom hook will unsubscribe from the argument value it was in charge of and subscribe to the new argument's value instead.
No extra effort is required on our part, which is pretty cool.
But enough theory, let's see a custom hook in practice.
This page is a preview of The newline Guide to Modernizing an Enterprise React App