Error Handling and Retry Logic for Failed Requests in React JS
Handling errors gracefully and implementing retry logic for failed HTTP requests are essential skills in React applications. This article explores how to manage errors and add retry logic using practical examples.
Example 1: Basic Error Handling
Handling errors ensures that your application can display meaningful messages to users when requests fail. Below is an example:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function BasicErrorHandling() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => setData(response.data))
.catch(err => {
console.error('Error fetching data:', err);
setError('Failed to fetch data. Please try again later.');
});
}, []);
return (
Basic Error Handling
{error ? {error}
: data ? (
Title: {data.title}
Body: {data.body}
) : Loading...
}
);
}
export default BasicErrorHandling;
Example 2: Retry Logic with Backoff
Retrying failed requests can improve reliability, especially when dealing with temporary network issues. Here is an example with retry logic:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function RetryLogic() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [retryCount, setRetryCount] = useState(0);
const fetchData = async (attempt = 1) => {
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
setData(response.data);
setError(null);
} catch (err) {
console.error(\`Attempt \${attempt} failed: \`, err);
if (attempt < 3) {
setTimeout(() => fetchData(attempt + 1), attempt * 1000); // Exponential backoff
} else {
setError('Failed to fetch data after multiple attempts. Please try again later.');
}
}
};
useEffect(() => {
fetchData();
}, []);
return (
Retry Logic with Backoff
{error ? {error}
: data ? (
Title: {data.title}
Body: {data.body}
) : Loading...
}
);
}
export default RetryLogic;
Example 3: Retry with User Trigger
Sometimes, retrying on user interaction, such as a button click, is more appropriate. Here's an example:
import React, { useState } from 'react';
import axios from 'axios';
function RetryOnClick() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');
setData(response.data);
} catch (err) {
console.error('Error fetching data:', err);
setError('Failed to fetch data. Click retry to try again.');
} finally {
setLoading(false);
}
};
return (
Retry on User Interaction
{error ? {error}
: data ? (
Title: {data.title}
Body: {data.body}
) : null}
);
}
export default RetryOnClick;
Best Practices
- Always provide clear error messages to users when a request fails.
- Limit retry attempts to avoid overwhelming the server.
- Use exponential backoff to space out retries.
- Provide users with manual retry options when appropriate.
By implementing error handling and retry logic, you can create more reliable and user-friendly React applications.