R

React Handbook

Clean • Professional

React Error Handling & Retry Strategies: Build Robust Apps

2 minute

React Error Handling & Retry Strategies

Building robust React applications means anticipating errors and handling them gracefully. Whether it’s network failures, API errors, or unexpected exceptions, proper error handling ensures your app doesn’t crash and keeps users informed. Additionally, retry strategies help recover from temporary issues automatically.

Why Error Handling is Important

learn code with durgesh images

  1. User Experience: Display friendly messages instead of broken pages.
  2. Reliability: Ensure the app continues working despite errors.
  3. Debugging: Log and track errors for developers to fix issues.
  4. Data Integrity: Avoid incomplete or corrupted data being shown to users.

Basic Error Handling in React

In functional components, you can handle errors using try-catch blocks during API calls:

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

function UserList() {
  const [users, setUsers] = useState([]);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchUsers = async () => {
      try {
        const response = await fetch("<https://jsonplaceholder.typicode.com/users>");
        if (!response.ok) throw new Error("Failed to fetch users!");
        const data = await response.json();
        setUsers(data);
      } catch (err) {
        setError(err.message);
      }
    };

    fetchUsers();
  }, []);

  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {users.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default UserList;
  • Wrap API calls in a try-catch block.
  • Set an error state and display it to the user.
  • Prevents the app from crashing on network or server errors.

Retry Strategies

Sometimes errors are temporary (e.g., network issues). You can implement retry logic to automatically re-fetch data:

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

function fetchWithRetry(url, retries = 3, delay = 1000) {
  return new Promise((resolve, reject) => {
    const attempt = (n) => {
      fetch(url)
        .then((res) => {
          if (!res.ok) throw new Error("Request failed");
          return res.json();
        })
        .then(resolve)
        .catch((err) => {
          if (n === 0) reject(err);
          else setTimeout(() => attempt(n - 1), delay);
        });
    };
    attempt(retries);
  });
}

function RetryExample() {
  const [data, setData] = useState([]);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetchWithRetry("<https://jsonplaceholder.typicode.com/users>")
      .then(setData)
      .catch((err) => setError(err.message));
  }, []);

  if (error) return <p>Error: {error}</p>;

  return (
    <ul>
      {data.map((user) => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default RetryExample;
  • fetchWithRetry attempts multiple fetch calls with a delay.
  • Reduces failure chances due to temporary network issues.
  • Improves robustness of your React application.

Using React Query / SWR for Automatic Retry

Libraries like React Query or SWR handle retrying failed requests automatically, along with caching, background refetching, and error states.

React Query Example:

import { useQuery } from "@tanstack/react-query";

function Users() {
  const { data, error, isLoading } = useQuery(
    ["users"],
    () => fetch("<https://jsonplaceholder.typicode.com/users>").then(res => res.json()),
    {
      retry: 3, // retry failed requests 3 times
      retryDelay: 1000,
    }
  );

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}
  • Automatic retries reduce boilerplate code.
  • Built-in error handling states: isLoading, error.
  • Simplifies robust API integration in React apps.

Article 0 of 0