React: From Components to Production · State, Events and Effects
Effects: Synchronizing with External Systems
Use useEffect for subscriptions and external sync — and know when you don't need it.
useEffect synchronizes a component with something outside React: subscriptions, timers, DOM APIs, WebSockets, non-React widgets. It runs after render; list every reactive value it uses in the dependency array and return a cleanup function. You don't need an effect to transform data for rendering or to respond to user events — do that during render or in handlers. React 19.2 adds useEffectEvent to read the latest values in effects without re-subscribing.
import { useEffect, useState } from "react";
export function OnlineStatus() {
const [online, setOnline] = useState(navigator.onLine);
useEffect(() => {
const update = () => setOnline(navigator.onLine);
window.addEventListener("online", update);
window.addEventListener("offline", update);
return () => {
window.removeEventListener("online", update);
window.removeEventListener("offline", update);
};
}, []);
return <span>{online ? "Online" : "Offline"}</span>;
}
// BUG: Not needed: derived data
// useEffect(() => setFullName(first + " " + last), [first, last]);
// FIX: const fullName = `${first} ${last}`;
Common pitfalls
- Missing dependencies (stale values) or suppressing the lint rule.
- Effects that set state derived from props, causing extra renders.
- No cleanup for subscriptions, intervals or fetches (race conditions).
Key points
- Effects sync with external systems
- Always clean up
- Derive data during render; handle events in handlers
Further reading: react.dev: You might not need an effect
Practice questions
When do you NOT need useEffect?
Answer
For computing values from props/state (do it during render), for responding to user actions (use event handlers), and for resetting state when a prop changes (use a key).
Why must an effect that subscribes to an event return a cleanup?
Answer
Otherwise each re-run or remount adds another listener, causing leaks and duplicate updates; cleanup removes the previous subscription.
Open in the app to mark lessons complete, take notes and track your progress.