Skip to main content

Command Palette

Search for a command to run...

Reusable Toggler with Custom React Hooks

Published
3 min read
D

Software Development Engineer at Amazon Web Services (AWS)

I was building things with Higher Order components, and if you're a Javascript pro they're pretty intuitive but they are large and clunky, and sometimes it's unclear what is happening in them, in my opinion.

As part of React's general overall move to embrace functional components, we have thrown out higher order components and replaced them with hooks.

Take a look at this higher-order component:

carbon.png

The above function is pretty understandable, but could be better. At first glance if you didn't know what HOCs are you could probably glean that there is a function within another function and you are passing a component through props to the inner component, and wrapping the passed component . This is weird though, and doesn't follow a pattern like you use really anywhere else in React.

If we were to refactor this into a custom hook, where both functions and variables can be passed directly to another function, we can skip passing things through props entirely. It's not totally clear in this simple example, because we are just passing JSX, but higher order components used to be a de-facto React way of passing things to a component.

Now take a look at the custom hook we create to share a toggler function and a variable in today's project:

carbon.png

First, we don't have to import the entire React library because we don't have to write any JSX in the function, we just import useState in order to keep track of a boolean variable. It's a convention to name a hook starting with the word use- so here we name our hook useToggler. Within the toggler we create a function that can be shared anywhere we want to use this hook.

One of the major benefits of hooks is that they're so reusable. Say you have a bunch of different timekeeping services on your website, for example, then a custom hook could share functions among all of those services. You can return data from the hook in an object, but then you're committing to not being able to rename the properties. If you return the data as an array as I've done here, you can later import the same data and call it whatever you want.

Here is a snippet of relevant code from the App.js component, where we import the useToggler custom hook and use it twice, for two separate toggling items (remember that reusability I mentioned?). I'll show you where we import the hook and set it up for use in both places:

carbon.png

You can see here that we call the useToggler hook twice- once for each piece of the application where we want to use it. Since we returned the data from the hook in an array, we can rename the returned items for what makes sense in each place of the application. Here is the first half of the App component where you can see we are using darkIsOff to determine if dark mode is on or not and using the generic toggler function to toggle the state true or false with the button:

carbon.png

And below is the second part of the App component which uses the same boolean variable and the same toggler function but coming from the custom hook that we called separately and renamed for this piece of the code. The state variable is named isJames here and the function toggleIsJames:

carbon.png

So even though it's a simple example you can see immediately that by writing custom hooks, which are just an emergent pattern of React, you can create widely reusable functions, variables, and even JSX for use anywhere in your application. Most importantly, it means you never have to create a higher order component again (if you don't want to) which I find comforting :)

Thank you