javascript / intermediate
Snippet
Exponential Backoff Error Recovery in React Async Actions
Network requests can encounter transient network glitches or rate limits. Instead of failing immediately on the first network error, an intermediate error handling pattern uses recursive exponential backoff to retry the request with increasing delays before surfacing the error to the React UI state.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { useState } from 'react';async function fetchWithRetry(url, retries = 3, delay = 500) {try {const res = await fetch(url);if (!res.ok) throw new Error(`HTTP Error: ${res.status}`);return await res.json();} catch (err) {if (retries <= 0) throw err;await new Promise((resolve) => setTimeout(resolve, delay));return fetchWithRetry(url, retries - 1, delay * 2);}}export function DataFetcher({ endpoint }) {const [status, setStatus] = useState({ data: null, error: null, loading: false });const handleLoad = async () => {setStatus({ data: null, error: null, loading: true });try {const result = await fetchWithRetry(endpoint);setStatus({ data: result, error: null, loading: false });} catch (err) {setStatus({ data: null, error: err.message, loading: false });}};return (<div><button onClick={handleLoad} disabled={status.loading}>Load Data</button>{status.error && <p role="alert">Failed: {status.error}</p>}{status.data && <pre>{JSON.stringify(status.data, null, 2)}</pre>}</div>);}
react
Breakdown
1
if (retries <= 0) throw err;
Terminates recursion and rethrows the final error when maximum retry attempts have been exhausted.
2
await new Promise((resolve) => setTimeout(resolve, delay));
Pauses execution asynchronously for the specified duration before attempting the next retry.
3
return fetchWithRetry(url, retries - 1, delay * 2);
Recursively invokes the fetch function with one fewer retry remaining and double the delay duration.