You Might Not Need an Effect
Effects (useEffect) are React's escape hatch for synchronizing with external systems. But most of the time, you don't need them. Removing unnecessary Effects makes code faster, simpler, and less error-prone.
Based on React Documentation: You Might Not Need an Effect
Transform Data During Rendering
Don't use Effects to transform data for display. Calculate it during render instead.
❌ Bad:
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
}
✅ Good:
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
const fullName = firstName + ' ' + lastName;
}
Why? Extra state causes unnecessary re-renders and cascading updates.
Cache Expensive Calculations
Wrap slow computations in useMemo to skip unnecessary recalculations.
function TodoList({ todos, filter }) {
const visibleTodos = useMemo(() => {
return getFilteredTodos(todos, filter);
}, [todos, filter]);
}
Only recalculates when todos or filter actually changes.
Handle User Events in Handlers
User actions belong in event handlers, not Effects.
❌ Bad:
useEffect(() => {
showNotification('Item added!');
}, [product]);
✅ Good:
function handleBuyClick() {
addToCart(product);
showNotification('Item added!');
}
Why? Effects don't know what happened—only that something changed.
Reset State with Keys
Use key prop to reset component state when navigating.
function ProfileList({ profiles }) {
return profiles.map(profile => (
<Profile key={profile.id} userId={profile.id} />
));
}
When key changes, React automatically resets that component's state.
Fetch Data Safely
Always add cleanup to fetch Effects to avoid race conditions.
useEffect(() => {
let ignore = false;
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(data => {
if (!ignore) {
setResults(data);
}
});
return () => { ignore = true; };
}, [query]);
Why? Prevents showing stale results when typing fast or navigating quickly.
Key Takeaways
| Use Effect For | Use Instead |
|---|---|
| Transform data | Calculate during render |
| User events | Event handlers |
| Expensive calcs | useMemo |
| Reset on navigation | key prop |
| App init once | Top-level module or root App |
| External sync | useSyncExternalStore |
| Parent communication | Pass data down (lift state up) |
| Fetch data | Add cleanup function |
Remember
Effects sync with external systems—network, browser APIs, third-party libraries. If it's about your own app's data, you probably don't need an Effect.