Article thumbnail

🔰 Manage components appearance with useToggle hook



Explore custom useToggle hook use cases. Implement, type, and test it. Compare code before and after useToggle implementation for a clear understanding.

Let's understand why you may need the useToggle hook

Usually when creating components like: Dialogs, Menus, Modals, and Alerts, you need a flag that determines whether should something be displayed or not. With this flag, you need to provide 3 functions: open, close, and toggle. It will probably looks like the following code:


Imagine that you have tons of components like mentioned one and in addition in your application logic, you need to determine whether to show something or hide.


The next case may require assigning some data when you want to display UI parts - for example, you want to edit user data, so you need to store somewhere the current user object, update this object, close the form, and reset the object to initial value or just null.


This code is easy to understand but hard to maintain - the same repetitive logic, hard coded in different places. You need to write repeated tests to cover these cases for every component that needs to show/hide UI or for components that store some data during toggling.

This is the moment when lights turn on and we're kicking in with easy to use and type-safe hook. This hook will be called useToggle - it was really hard for me to find the appropriate name for this hook.

How we will use the useToggle hook?

We want to make this hook "flat" as possible to reduce the number of lines. So it will be used in the following way:


It's insane how we reduced the code from the previous example. Let's explore the full API of this hook:


Creating type definitions in TypeScript

Contracts in terms of type-safety are required to achieve protection from typos, invalid usage of functions, and invalid usage of returned data. Let's create them in separate file:


We've used generics T and we assigned the initial type to null. It means if we skip providing the generic type to hook, the default data type will be null.

Implementation process of the useToggle hook

Now it's time for implementation. With before-created type definitions, we'll be safe during implementation. Look at the following gif to understand the order and implementation process with defined contracts.


Ok, we know how it was implemented so let's explain each part of this implementation.


Now is the time for unit tests!

Unit tests for useToggle hook

We'll use the react-testing-library module that allows us to test hooks. We'll try to go through the typical use case of this hook and we'll check if the state changed correctly.


We started by assigning the initial state to our hook via configuration and then we closed, opened, toggled, and reassigned data. After each interaction, we checked the state.

Final result

Repository to play with implemented code. In addition below you have all the required code Copy and paste it and just use useToggle hook.

Look at type definitions file.


Now the implementation kicks in.


In the end the really important part - tests.


What did we learn in this lesson?

As you have probably seen, sometimes simple logic can be frustrating to work with if you need to repeat such logic in different places. This simple useToggle hook shows how you can wrap such logic inside a reusable, independent being.

What scenarios can be handled with this utility? It may be useful in creating any components like Modal, Menu, in simple words - to create something that appears and disappears.

In addition, we can assign additional data that may be useful when dealing with real business requirements or more complex components.

Everything is tested in a single place, so next time when you'll test your components you need to focus only on checking - is the useToggle hook used? If yes, you can skip testing these flags and data setup in your application/presentation-related components.

I create content regularly!

I hope you found my post interesting. If so, maybe you'll take a peek at my LinkedIn, where I publish posts daily.


Add your honest opinion about this article and help us improve the content.

created: 20-03-2023
updated: 20-03-2023