When to Use useEffect
In this tutorial we will learn exactly when useEffect is appropriate in React 19 and, more importantly, when it is not needed. Many beginners overuse useEffect, causing unnecessary complexity and bugs. By the end, you will understand the modern rules for using useEffect correctly and how React 19 + the React Compiler have reduced the need for effects dramatically.
What useEffect Really Does
useEffect lets you run code after React renders the UI.
It is for synchronizing React with external systems, such as:
- browser APIs
- network subscriptions
- event listeners
- third-party libraries
If your code affects something outside React, you probably need an effect.
If your code only affects React state or UI, you probably do not need it.
When You SHOULD Use useEffect
Below are the valid, modern use cases.
1. Subscribing to External Systems
Example: listening to browser events.
useEffect(() => {
function handleResize() {
console.log(window.innerWidth);
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);Use this for:
- WebSocket or SSE connections
- browser event listeners
- observers (IntersectionObserver, MutationObserver)
2. Integrating with Third-Party Libraries
Example: initializing a chart, map, or widget.
useEffect(() => {
const map = new MapLibrary.Map("#map");
}, []);If a library requires imperative setup, useEffect is correct.
3. Reading Browser-Only APIs
Some APIs aren’t available during server rendering.
Example:
useEffect(() => {
console.log("URL:", window.location.href);
}, []);4. Running Code When Something Changes Outside React
If you must synchronize some state with the DOM or an external system, useEffect is appropriate.
Example: updating document title manually (although JSX metadata is preferred):
useEffect(() => {
document.title = `Hello ${name}`;
}, [name]);When NOT To Use useEffect
React 19 eliminates many old reasons developers used useEffect.
Here are the most important anti-patterns.
1. DON’T Fetch Data in useEffect
Modern React uses:
- Actions
- the
use()API - server functions
- frameworks that support server components
Fetching in an effect causes:
- double-render flashing
- loading states
- waterfalls of requests
- inconsistent data
Instead, use:
const data = use(fetchUser());Or, if using an Action-powered flow, keep data loading on the server.
2. DON’T Derive State in useEffect
Incorrect:
useEffect(() => {
setFullName(first + " " + last);
}, [first, last]);React can calculate this directly:
const fullName = `${first} ${last}`;Derived state does not belong in effects.
3. DON’T Sync Props to State
Incorrect:
useEffect(() => {
setUser(props.user);
}, [props.user]);If you need the prop, just use the prop. If you need controlled state, initialize it from props once during server rendering.
4. DON’T Trigger Actions Inside useEffect
Effects should not fire network updates or server mutations. Use Actions and forms, not effects, for server updates.
5. DON’T Use useEffect for Rendering Logic
Incorrect:
useEffect(() => {
if (count > 5) {
setShowWarning(true);
}
}, [count]);Use simple conditional rendering:
const showWarning = count > 5;6. DON’T Use useEffect to Keep UI in Sync with State
React already does this automatically.
Example of unnecessary effect:
useEffect(() => {
console.log("Count changed");
}, [count]);Only log in effects when you're debugging or interacting with external systems.
A Helpful Mental Model
Ask yourself:
"Does this code need to run outside React?"
If yes, use useEffect.
If no, do not use it.
Effects are for:
- external subscriptions
- DOM APIs
- side-effects
- imperative libraries
They are not for:
- data fetching
- calculations
- setting state based on props
- triggering UI changes
- performing component logic
In Short
| Task | Use useEffect? |
Why |
|---|---|---|
| Fetching data | No | Use Actions or use() |
| Subscribing to WebSocket | Yes | External system |
| Calculating values | No | Use variables |
| Updating DOM manually | Yes | Side effect |
| Running animations (imperative) | Yes | External API |
| Updating server data | No | Use Actions |
| Logging inside React | Rarely | Often not necessary |
useEffect is no longer a “default tool” for everything in React. In React 19, you use it only when interacting with systems outside React. For most tasks that beginners used effects for in the past, React now provides better, simpler tools like Actions, the use() API, and automatic compiler optimizations.