As someone who's written React for several years now, it took me far too long to discover the joy of custom hooks - in fact it took me over 3 years! In this post, I'm going to show you how to take advantage of one of React's most powerful features.
What even is a hook?
A hook is quite simply a function which lets you hook into React's rendering lifecycle. Let's briefly look at the most common hook useState
:
const [state, setState] = useState(0)
As you can see, useState
hooks into React and provides an interface for managing state - it's entirely abstracted away the complexity that would otherwise be associated with it.
When we think of hooks as reusable abstractions, it makes them easier to reason about. As a component is reusable markup, a hook is just reusable logic!
I like to refer to React's built-in hooks as atomic - in that we typically use and combine them to build our own custom ones.
Our first custom hook
Let's build a basic custom hook to manage the state of a toggleable component (modal, dropdown, etc):
useToggle.ts
import { useState } from "react";
function useToggle(initial = false) {
const [state, setState] = useState(initial);
return [
state,
{
open: () => setState(true),
close: () => setState(false),
toggle: () => setState((state) => !state)
}
] as const;
}
export default useToggle;
Quick tip: using
as const
on our return value tells TypeScript to infer the type as a readonly tuple instead of a union type array! 😁
In this example, all we've done is wrap the use state hook with some logic that would otherwise pollute a component - look how easy it is to implement:
App.tsx
function App() {
const [state, { open, close, toggle }] = useToggle();
return (
<div className="App">
<button onClick={open}>Open</button>
<button onClick={close}>Close</button>
<button onClick={toggle}>Toggle</button>
{state && <div>Hello!</div>}
</div>
);
}
...and that's it! I hope that after seeing this you can start to see how you might implement other hooks - try useQueue
and useStack
.
In a future post I'll detail how to implement some more complicated behaviour, and some common design patterns for handling refs, external data and more.
Top comments (1)
Why create one when you can get all awesome hooks in a single library?
Try scriptkavi/hooks. Copy paste style and easy to integrate with its own CLI