The undoubted advantage of React Hooks is how easily we can extract logic fragments into our Hooks. In this post, I will show you how to write your Hooks, what the rules are, and how to make your code better!
But first, Let me show you the real benefits of react Hooks:
- Custom hooks are just functions and therefore easier to understand what they do.
- No need to deal with
this
. It becomes a pain when binding functions when we need to use an event handler. - The syntax is much shorter, which means there is less chance of bugs.
- The condition is more detailed. Instead of one big state object, we can have several small hooks and each work with its own state and our components use them all together. This way we avoid merging the new state with the old one and prevent unnecessary overwrites.
Custom React Hook
We follow the same rules for creating our own Hooks as for the built-in ones: each Hook name must begin with "use". Hook is a normal function, and inside it, we can call other functions! Thanks to this, the composition of many Hooks becomes extremely simple and does not require any complicated techniques. These are just the usual functions.
usePageTitle
Let's start with something simple: A hook that changes the title of the page to the given one.
It's a very simple, not to say naive implementation, but it does the job for sure. How to make your own hook out of it?
Then in the component, we will use it like this:
useDocumentTitle('My React hook');
Wow, that was easy, wasn't it? We created a normal function where we call hook and that's it, just like that.
Let's add something else, like restoring the original title when the component is unmounted:
Here, in the line marked with number 1, we write the existing one document.title
to the reef.
Then in the second one useEffect
we return the function that will be called only when unmounting the component and set it document.title
to the original value stored in the ref.
usePrevious
Sometimes we need information about the previous value of given props. While there was no problem with this in classes, in functional components we have to take care of it ourselves:
In this case, we create an empty ref (1), return the previous value (2), and then write to the ref a new one (3). This is because it useEffect
starts asynchronously.
Most often, however, instead of using it usePrevious
, we can solve the same problem differently and more simply, by adding a given prop to the dependency table useEffect
. Then React will compare the old and the new value for us!
useApi
What if ... We want fetch data from API using Hook? It's easy! Let's take code similar to the one in the Hooks and API article and replace it with our own Hook that we can use in many places in our application. The first approach looks like this:
As you can see it's not very good yet, but it works pretty well:
We can improve our Hook in two ways:
First, get rid of the logic responsible for retrieving data from the API - that is, it is something completely independent of React. We want to evoke just getData(…)
that, and not worry about some res.json()
or another similar thing. For example (simplifying):
The second fix would be to use useReducer
to get rid of excess code from useEffect
itself:
The code is much longer, but it also seems more readable to me, because the elements of independent logic have been separated from each other.
See, making your own React hooks is easier than you think. 😁
Top comments (1)
Hooks are awesome 🤩 never liked the classes anyway 😉