Reconnection, Error Handling & Cleanup
Handle disconnections gracefully and clean up socket listeners in useEffect.
Reconnection, Error Handling & Cleanup is a free React Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Reconnection Matters
Network interruptions are common on mobile. Without reconnection logic, users silently lose their real-time connection. A good strategy retries automatically with backoff.
Socket.IO Auto-Reconnect
Socket.IO reconnects automatically by default. Configure reconnectionAttempts, reconnectionDelay, and reconnectionDelayMax in the io() options.
const socket = io('https://api.example.com', {
reconnectionAttempts: 5,
reconnectionDelay: 1000, // initial delay
reconnectionDelayMax: 10000, // max delay (exponential backoff)
randomizationFactor: 0.5,
});Tracking Connection State in React
Listen to connect, disconnect, and connect_error events and reflect the status in component state.
function useConnectionStatus() {
const [status, setStatus] = useState<'connected' | 'disconnected' | 'error'>(
socket.connected ? 'connected' : 'disconnected'
);
useEffect(() => {
socket.on('connect', () => setStatus('connected'));
socket.on('disconnect', () => setStatus('disconnected'));
socket.on('connect_error', () => setStatus('error'));
return () => {
socket.off('connect');
socket.off('disconnect');
socket.off('connect_error');
};
}, []);
return status;
}Showing a Reconnection Banner
Display a banner when the socket disconnects so users know they're offline and reconnection is in progress.
function ConnectionBanner() {
const status = useConnectionStatus();
if (status === 'connected') return null;
return (
<div className="banner warning">
{status === 'error' ? 'Connection failed' : 'Reconnecting...'}
</div>
);
}Manual Reconnection
After exhausting retries, let users trigger a manual reconnect via a button.
const [failed, setFailed] = useState(false);
socket.on('reconnect_failed', () => setFailed(true));
if (failed) {
return (
<button onClick={() => { setFailed(false); socket.connect(); }}>
Retry connection
</button>
);
}Raw WebSocket Reconnection
Raw WebSocket has no built-in reconnect. Implement exponential backoff manually: on close, wait Math.min(delay * 2, maxDelay) before attempting a new connection.
function connectWithBackoff(url, attempt = 0) {
const ws = new WebSocket(url);
ws.onclose = () => {
const delay = Math.min(1000 * 2 ** attempt, 30000);
setTimeout(() => connectWithBackoff(url, attempt + 1), delay);
};
return ws;
}Cleanup in useEffect
Every socket listener added in a useEffect must be removed in the cleanup function. Failing to do so causes memory leaks and duplicate event handling.
useEffect(() => {
const onData = (d) => setState(d);
socket.on('data', onData);
return () => {
socket.off('data', onData); // remove specific handler reference
};
}, []);Avoiding Stale Closures in Handlers
When a socket handler references state or props, it captures a stale closure. Use a ref to always access the latest value.
const handlerRef = useRef(null);
handlerRef.current = (msg) => updateMessages(messages, msg); // fresh ref each render
useEffect(() => {
const onMsg = (...args) => handlerRef.current(...args);
socket.on('message', onMsg);
return () => socket.off('message', onMsg);
}, []); // no deps neededFlushing Pending Messages on Reconnect
Queue outgoing messages while disconnected and flush the queue when the connection re-establishes.
const queue = useRef<string[]>([]);
socket.on('connect', () => {
while (queue.current.length) {
socket.emit('message', queue.current.shift());
}
});
function send(text: string) {
if (socket.connected) socket.emit('message', text);
else queue.current.push(text);
}Rejoining Rooms After Reconnect
Socket.IO clears room memberships on disconnect. Rejoin rooms when the socket reconnects to restore subscriptions.
useEffect(() => {
function rejoin() { socket.emit('join-room', roomId); }
socket.on('connect', rejoin);
return () => socket.off('connect', rejoin);
}, [roomId]);Global Error Handling
Handle unrecoverable errors gracefully: show an error UI and offer a page reload as the last resort.
socket.on('connect_error', (err) => {
console.error('Socket error:', err.message);
// Show user-friendly error
});Quick Check
What is the risk of not removing a socket event listener in useEffect cleanup?
Recap
Configure Socket.IO reconnection with backoff options. Reflect connection status in React state, show a reconnection banner, rejoin rooms after reconnect, and always remove listeners in useEffect cleanup. Queue pending messages while offline and flush on reconnect.
Frequently asked questions
Is the “Reconnection, Error Handling & Cleanup” lesson free?
Yes — the full text of “Reconnection, Error Handling & Cleanup” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Reconnection, Error Handling & Cleanup”?
Handle disconnections gracefully and clean up socket listeners in useEffect. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Reconnection, Error Handling & Cleanup” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- WebSocket Fundamentals in the Browser
- Using Socket.IO with React
- Building a Real-Time Chat Component
- Reconnection, Error Handling & Cleanup