useFetch(): My most used react custom hook

Fetching data efficiently

useFetch(): My most used react custom hook

Hey, this is me Ashik Chapagain here.

Introduction

Whenever we need to fetch the data from API in React we use fetch inside useEffect and repeat the same in every component.

Like this.

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

export default function HomePage() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts');
      const json = await res.json();
      setData(json);
    };
    fetchData();
  }, []);

  return (
    <div>
      {data &&
        data.map(post => (
          <div style={{ marginBottom: '20px' }}>{post.title}</div>
        ))}
    </div>
  );
}

But, But, But. ✋✋ Do you know you can do the same task more efficiently using a custom react hook?

import React from 'react';
import useFetch from '../hooks/useFetch.js';

export default function HomePage() {
  const { loading, error, data } = useFetch(
    'https://jsonplaceholder.typicode.com/posts'
  );

  if (loading) return 'Loading...';
  if (error) return 'Error Occured';

  return (
    <div>
      {data.map(post => (
        <div style={{ marginBottom: '20px' }}>{post.title}</div>
      ))}
    </div>
  );
}

Look at the difference, we have loading and error too in the second example.

Let's Build

Create a new folder hooks in the root directory and touch useFetch.js. image.png

Add the following content to useFetch.js

import { useEffect, useState } from 'react';

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

  useEffect(() => {
    const fetchData = async () => {
      setLoading(true);

      try {
        const res = await fetch(url);
        const json = await res.json();
        setData(json);
        setLoading(false);
      } catch (error) {
        setError(error);
        setLoading(false);
      }
    };
    fetchData();
  }, [url]);

  return { loading, error, data };
};

export default useFetch;

Now use it wherever it's needed.

How to use it?

import React from 'react';
import useFetch from '../hooks/useFetch.js';

export default function HomePage() {
  const { loading, error, data } = useFetch(
    'https://jsonplaceholder.typicode.com/posts'
  );

  if (loading) return 'Loading...';
  if (error) return 'Error Occured';

  return (
    <div>
      {data.map(post => (
        <div style={{ marginBottom: '20px' }}>{post.title}</div>
      ))}
    </div>
  );
}

Thanks for reading this article.

Let's connect on:

If you like this article, don't forget to react to this article.