Custom Hooks in TypeScript
Sharing stateful logic among components is important for reusability, especially when we have UI components that are used in multiple places throughout our code and whose logic we want to control from their parent. The use cases for this would be fetching data, accordions/modals that conditionally open and close, pagination components and etc.
For better code structure, I usually create a hooks
folder inside src.
As for the filename, React requires hooks to start with use.
So we can create a new file with the name useToggle.tsx
for our example and define types:
import { useState } from "react";export const useToggle = (): [boolean, () => void] => {// rest of the code};
At the top, we have an import statement for useState
hook that we will be using to define the state for our custom hook, then we have a function expression with no arguments and its return type. The return type for custom hooks is an array that returns elements of the values that are being returned. If we need only one value then we can return one element in the array. Inside the array, we have to declare what type each element will be in order otherwise TypeScript will assume one type for the array and throw errors once we start using elements with other types. In this case, we return 2 elements: one boolean value and one pure function (meaning function that just updates something and doesn’t return anything). Let’s define what these should be:
// inside useToggleconst [toggleOn, setToggleOn] = useState<boolean>(false);const updateToggle = () => { setToggleOn((prevToggleOn) => !prevToggleOn);};return [toggleOn, updateToggle];
We have toggleOn
that stores a boolean value, initially set to false and we have a method updateToggle
that will be in charge of switching the toggle from on to off and vice versa. It takes the previous state and sets the new state as the opposite of the previous one. If we wanted to return just setToggleOn
hook instead of updateToggle,
return type would also be different and would be `React.Dispatch<React.SetStateAction>` instead. Now let’s put our custom hook to use:
import { useToggle } from "./useToggle";export default function App() { const [toggleOn, updateToggle] = useToggle(); return ( <div className="App">
<button
onClick={updateToggle}>
{toggleOn ? "ON" : "OFF"}
</button>
</div> );}
We use array restructured to get the imported object from our custom hook and then use it in our UI. We are attaching updateToggle
to our button onClick event and we are using toggleOn
to determine which text to display on the button.
Happy typing:)
If you would like to see TypeScript video tutorials, please check out my channel:
https://www.youtube.com/channel/UCObrjoZZJSjznfCO5Vx9qUQ