Hooks are functions that can be called inside functional components to add various capabilities.

React Hooks provide a way to add stateful logic to functional components in React. They were introduced in React version 16.8 as a way to write reusable and more concise code compared to using class components and lifecycle methods.

With React Hooks, we can use built-in hooks like useState, useEffect, useContextuseMemo etc., or create your own custom hooks

In this article we will learn how to create our very own custom react hooks. Before we start, let's see an example.

Example: 1

We need a toggle button that allows the user to switch between the dark or light mode of the application.

toggle color mode

In React, we can do this easily.

const SwitchColorMode = () => {
  const [colorMode, colorModeSet] = useState(false);

  const handleClick = useCallback(() => {
    colorModeSet((prevState) => !prevState);
  }, []);

  return (
    <div className="wrapper">
      <label>Color Mode</label>
      <button onClick={handleClick}>
        {colorMode ? 'on' : 'off'}
      </button>
    </div>
  );
};

That is the simplest approach to achieve the toggle functionality.

Example: 2

What if, we need another component that shows and hides the content?

We will follow the same approach.

const Accordion = () => {
  const [open, openSet] = useState(false);

  const handleClick = useCallback(() => {
    open((prevState) => !prevState);
  }, []);

  return (
    <div className="wrapper">
      <label onClick={handleClick}>Click me to learn more..</label>
      {open && <>Hello There!</>}
    </div>
  );
};

See, in both examples, the logic is the same. That means we can separate the behavior from the UI. For that, we can create a simple hook that just manages the boolean state in a concise and reusable way.

Build Your Own Custom React Hook

Let's create a custom hook for the above example.

import { useState } from 'react';


function useToggle(initialValue = false) {
  const [state, stateSet] = useState(initialValue);

  function toggle() {
    stateSet(prevState => !prevState);
  }

  return [state, toggle];
}

 

In this example, we define a custom hook called useToggle that initializes a boolean state with an initial value defaulting to false.

It returns an array with two elements: the current boolean value and a toggle function.

The toggle function uses the stateSet function provided by the useState hook to toggle the boolean value.

Using the custom hook:

function ToggleComponent() {
  const [isToggled, toggle] = useToggle(false);

  return (
    <div className="wrapper">
      <label>Color Mode</label>
      <button onClick={toggle}>
        {isToggled ? 'on' : 'off'}
      </button>
    </div>

  );
}

export default ToggleComponent;

 

In the ToggleComponent, we use the useToggle hook to get the current boolean value (isToggled) and the toggle function.

We render a button that displays 'ON' or 'OFF' based on the boolean value and toggles it when clicked.

Whenever the button is clicked, the toggle function is called, which updates the boolean value and triggers a re-render of the component, reflecting the updated state.

By combining the logic into a single custom hook, we can reuse it easily throughout our application, keeping our code more concise and maintainable.