Clean β’ Professional
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.

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;
try-catch block.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.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>
);
}
isLoading, error.