How to build custom hooks in React

How to build custom hooks in React

React hooks, first introduced in React 16.8. Let you use state and some other React features without writing a class.

As a React developer, it’s key to learn how to create custom hooks to add missing features and reduce repetitive logic in your React Application.

What are custom hooks

Custom hooks are javascript functions that let you extract component logic into reusable codes. These functions are prefixed with the word use.

When is the right time to use custom hooks?

Let’s say you have two components that use the same logic to do a certain task, instead of writing that code twice in both components, you can create a custom hook that contains this logic and then use it as a function in your components. This way you don’t have to write more code.


In this step-by-step guide, I’ll show you how to create your own custom hooks and implement them in react components.

import React, { useEffect, useState } from "react";

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

  useEffect(() => {
    setTimeout(() => {
      fetch("https://icanhazdadjoke.com", {
        headers: {
          Accept: "application/json",
        },
      })
        .then((response) => {
          if (!response.ok) {
            throw Error("could not fetch data");
          }
          return response.json();
        })
        .then((data) => {
          setData(data.joke);
          setLoading(false);
          setError(null);
        })
        .catch((error) => {
          setLoading(false);
          setError(error.message);
        });
    }, 1000);
  }, []);

  return <h1>{data}</h1>;
};

export default Dadjokes;

This is what a component on the app that we'll be working with looks like, I'll drop the GitHub repository of the final project at the end of this article.

By merely taking a glance at the code snippet, you can tell that this component sends an API request to a certain endpoint upon render.

Now let's assume that we want to make this type of request in another component, We'll have to write all those codes again right?

Well by creating a custom hook with those codes in it, we won't have to write all of them again if we want to send an API request from another component. We'll just have to import the custom hook and parse the necessary arguments if needed.

Creating the custom hook

Step 1

Create a separate file on your React Application and name it whatever you want, if you're following this tutorial with the source code on GitHub, you would notice that the name of my custom hook file is useFetch, chose the name because the file will contain all our data fetching logic.

Step 2

Create a function with the prefix "use", please note that this is very important, if your function name doesn't start with "use", the custom hook won't work.

const useFetch = () => {


};

export default useFetch;
`

exporting the function makes it available to use in other components.

Step 3

Paste the data fetching logic in your function.

import { useState, useEffect } from "react";

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

  useEffect(() => {
    setTimeout(() => {
      fetch(url, {
        headers: {
          Accept: "application/json",
        },
      })
        .then((response) => {
          if (!response.ok) {
            throw Error("could not fetch data");
          }
          return response.json();
        })
        .then((data) => {
          setData(data.joke);
          setLoading(false);
          setError(null);
        })
        .catch((error) => {
          setLoading(false);
          setError(error.message);
        });
    }, 1000);
  }, [url]);
};

export default useFetch;

Step 4

Add a return value to your function, these values will be what you'll be able to access when you use this custom hook. In this example, our function will return an object with three values. Your return value can be anything.

import { useState, useEffect } from "react";

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

  useEffect(() => {
    setTimeout(() => {
      fetch(url, {
        headers: {
          Accept: "application/json",
        },
      })
        .then((response) => {
          if (!response.ok) {
            throw Error("could not fetch data");
          }
          return response.json();
        })
        .then((data) => {
          setData(data.joke);
          setLoading(false);
          setError(null);
        })
        .catch((error) => {
          setLoading(false);
          setError(error.message);
        });
    }, 1000);
  }, [url]);

  return {data,loading,error}    <----------
};

export default useFetch;

Step 5

import the custom hook in your desired component and use it!

import React from "react";
import useFetch from "../useFetch";

const Dadjokes = () => {
  const { data, loading, error } = useFetch("https://icanhazdadjoke.com") <------
  return (
    <div>
      {loading && <h1>loading...</h1>}
      {data && <h1>{data}</h1>}
      {error && <h1>{error}</h1>}
    </div>
  );
};

export default Dadjokes;

Conclusion

Custom hooks are Javascript functions that start with use, can call other hooks and allows you to extract reusable logic.

You can find the code for this tutorial on Github

Please, feel free to ask if you have any questions in the comment section.

Thanks for reading, see you soon!