Skip to content

useFetch

React hook to fetch data from an API.

Add the hook via the CLI:

sh
npx @novajslabs/cli add useFetch
sh
npx @novajslabs/cli add useFetch
sh
pnpm dlx @novajslabs/cli add useFetch

Or copy and paste the code into your project:

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

// Define the interface for the data returned by the API.
interface Data {}

// Define the interface for the error returned by the API.
interface Error {}

export const useFetch = (url: string, reqOpt?: RequestInit) => {
  const [data, setData] = useState<Data>();
  const [error, setError] = useState<Error>();
  const [isLoading, setIsLoading] = useState(false);
  const [isSuccess, setIsSuccess] = useState(false);

  const fetchData = async () => {
    setIsLoading(true);

    try {
      const res = await fetch(url, reqOpt && reqOpt);
      const data = await res.json();

      if (res.status === 200) {
        setIsSuccess(true);
        setData(data);
        setError(undefined);
      } else {
        setIsSuccess(false);
        setError(data);
        setData(undefined);
      }
    } catch (e) {
      setIsSuccess(false);
      setData(undefined);
      if (e instanceof Error) {
        setError(e);
      }
    }

    setIsLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, []);

  const refetch = () => fetchData();

  return { data, error, isLoading, isError: !isSuccess, isSuccess, refetch };
};
js
import { useState, useEffect } from "react";

export const useFetch = (url, reqOpt) => {
  const [data, setData] = useState();
  const [error, setError] = useState();
  const [isLoading, setIsLoading] = useState(false);
  const [isSuccess, setIsSuccess] = useState(false);

  const fetchData = async () => {
    setIsLoading(true);

    try {
      const res = await fetch(url, reqOpt && reqOpt);
      const data = await res.json();

      if (res.status === 200) {
        setIsSuccess(true);
        setData(data);
        setError(undefined);
      } else {
        setIsSuccess(false);
        setError(data);
        setData(undefined);
      }
    } catch (e) {
      setIsSuccess(false);
      setData(undefined);
      if (e instanceof Error) {
        setError(e);
      }
    }

    setIsLoading(false);
  };

  useEffect(() => {
    fetchData();
  }, []);

  const refetch = () => fetchData();

  return { data, error, isLoading, isError: !isSuccess, isSuccess, refetch };
};

Requirements

React 16.8 or higher

Parameters

url required

Type: string

The URL of the API endpoint.

reqOpt

Type: RequestInit

An object that contains any custom settings that you want to apply to the request. It is the same object that is passed to the JavaScript fetch function.

Return values

data

The data object for the query, if an error was not thrown.

error

The error object for the query, if an error was thrown.

isLoading

Type: boolean

Represents whether data is being fetched (true) or not (false).

isError

Type: boolean

Represents whether an error occurred while fetching the data (true) or not (false).

isSuccess

Type: boolean

Represents whether the data fetch was successful (true) or not (false).

refetch

Type: function

Manually refetch the query.

Example

tsx
import { useFetch } from "./hooks/useFetch";

const App = () => {
  const { data, error, isLoading, isError, isSuccess, refetch } = useFetch(
    "https://api.quotable.io/random"
  );

  if (isLoading) {
    return <span>Loading...</span>;
  }

  if (isError) {
    console.log(error);
    return <span>Error</span>;
  }

  if (isSuccess) {
    console.log(data);
  }

  return (
    <div>
      <p>{data && data.content}</p>
      <button onClick={refetch}>Another quote</button>
    </div>
  );
};

export default App;

Use cases

Here are some use cases where this React hook is useful:

  • Fetching real-time weather data from an API in a weather forecast web application
  • Retrieving user profile information from a server in a social media dashboard
  • Loading product details from an e-commerce API in a product catalog website

Released under the MIT License.