DEV Community

Cover image for Custom hooks in React
Rahul Khatri
Rahul Khatri

Posted on

Custom hooks in React

Hey👋 Devs,

Before get into the topic let's understand what is hooks in React.

Hooks allow to use state and other React features in functional components, making them more powerful and flexible.
There's already one general hook, useState that an array and the first element of an array is value and second one is a function to update the value.

const [toggle, setToggle] = useState(false)
Enter fullscreen mode Exit fullscreen mode

In above snippet, useState takes initial value false as an argument and returning an array, here is toggle vale and the setToggle is a function that update the toggle.

useState hook has there own logic to provide these value in more efficient way.

What is Custom Hook?

A Custom Hook is a function that allows to extract logic from a component and reuse it across multiple components.

Custom Hooks start with the word "use" and can use other Hooks, such as useState and useEffect, to create the logic that our want to extract from our components.

Here's a simple example, we use toggles a lot on the web, so this would be the logic to handle them

const MyComponent = () => {
  const [toggle, setToggle] = useState(false);

  const handleToggle = () => {
    setToggle(!toggle);
  };

  return <button onClick={handleToggle}>Toggle {toggle ? "Off" : "On"}</button>;
};

Enter fullscreen mode Exit fullscreen mode

As you can see, we define a toggle state and a handle function to update the toggle. This code pattern will also apply if we have multiple toggles in the same project.

Now here Custom Hook come into the picture

import { useState } from "react";

const useToggle = (initialValue) => {
  const [toggle, setToggle] = useState(initialValue);

  const handleToggle = () => {
    setToggle(!toggle);
  };

  return [toggle, handleToggle];
};

Enter fullscreen mode Exit fullscreen mode
// import useToggle hook 

const MyComponent = () => {
  const [toggle, handleToggle] = useToggle(false);

  return <button onClick={handleToggle}>Toggle {toggle ? "Off" : "On"}</button>;
};
Enter fullscreen mode Exit fullscreen mode

The useToggle hook contain the logic we defined in MyComponent component and the interesting thing is that we can reuse this logic in every component with the help of hook.

Let have look on another example

When fetching data from an API we generally use state for loading, error and data. Here's what it would look like

import { useState, useEffect } from "react";

const MyComponent = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(
          "https://jsonplaceholder.typicode.com/todos"
        );
        const data = await response.json();
        setData(data);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    }

    fetchData();
  }, []);

  if (loading) {
    return <Loader />;
  }

  if (error) {
    return <div>{error.message}</div>;
  }

  return <div>{/* render data */}</div>;
};

Enter fullscreen mode Exit fullscreen mode

In the above example, we defined states for data, loading, and error and used the useEffect hook to get data from the API. We know that's a general pattern to get data from any API. Instead of writing all this stuff in every component, make a hook for this pattern (logic) so every component can fetch data api without writing anything new

import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await fetch(url);
        const data = await response.json();
        setData(data);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    }

    fetchData();
  }, [url]);

  return { data, loading, error };
}

export default useFetch;

Enter fullscreen mode Exit fullscreen mode

The useFetch hook takes in a url parameter and returns an object with three states: data, loading, and error.

The useEffect hook is used to fetch the data from the specified url using the fetch() API. If the fetch is successful, the data state is updated with the fetched data, and loading is set to false. If there's an error, the error state is set to the error object, and loading is set to false.

The useFetch hook can be used in a component like this:

// import useFetch hook

function MyComponent() {
  const { data, loading, error } = useFetch("https://jsonplaceholder.typicode.com/todos");

  if (loading) {
    return <p>Loading...</p>;
  }

  if (error) {
    return <p>{error.message}</p>;
  }

  return <div>{/* render data */}</div>;
}

Enter fullscreen mode Exit fullscreen mode

In this example, the MyComponent component uses the useFetch hook to fetch data from the specified URL. It checks the loading and error states to determine what to render while waiting for the data to load. Once the data is available, it can be rendered as desired.

Benefits of Custom Hooks

  • First, they allow you to extract logic from your components and reuse it across multiple components, reducing the amount of code you need to write. This makes your code more readable and maintainable.

  • Second, Custom Hooks allow you to separate concerns and create more modular code. By extracting logic into Custom Hooks, you can focus on the specific functionality of each component and avoid duplicating code across multiple components.

  • Finally, Custom Hooks allow you to create reusable code that can be shared across multiple projects. By creating Custom Hooks that encapsulate specific functionality, you can build a library of reusable components that can be used across different projects. This saves time and reduces the amount of code you need to write.

Conclusion

In conclusion, Custom Hooks are a powerful tool in React that allow you to extract logic from your components and reuse it across multiple components. By using Custom Hooks, you can create more readable and maintainable code, reduce the amount of code you need to write, and create reusable code that can be shared across multiple projects.

Did you create any Custom Hook in react? Let me know in comment👇🏻

Top comments (3)

Collapse
 
scriptvirus profile image
scriptvirus

nice!👍👍👍🐮🍺 get it 3Q

Collapse
 
chiragsoni81245 profile image
Chirag Soni

I'm glad you shared this Rahul. That's a really clear and straightforward explanation of custom hooks. Also, the examples were great.

Collapse
 
rahul72925 profile image
Rahul Khatri

Thank you Chirag