useEffect and useLayoutEffect
useEffect = after render, useLayoutEffect = before paint
useEffect
"Side effects after render"
useEffect lets you perform side effects in function components.
"useEffect handles side effects like API calls, subscriptions, or DOM manipulation that run after the component renders."
Basic Syntax
useEffect(callback, dependencies)
useEffect(() => {
// Side effect
document.title = `Count: ${count}`;
}, [count]); // Dependencies
"useEffect takes a callback function and an optional dependency array that controls when the effect runs."
Dependency Array
Empty [] = mount, [dep] = when dep changes, none = every render
// Runs on every render
useEffect(() => {
console.log("Every render");
});
// Runs once on mount
useEffect(() => {
console.log("Mount only");
}, []);
// Runs when count changes
useEffect(() => {
console.log("Count changed");
}, [count]);
"The dependency array controls effect execution: empty array runs once, with dependencies runs when they change, no array runs every render."
Cleanup Function
Return function for cleanup
useEffect(() => {
const subscription = subscribe();
return () => {
// Cleanup
subscription.unsubscribe();
};
}, []);
Cleanup runs:
- Before re-running effect (if deps change)
- On unmount
"Return a cleanup function from useEffect to clean up subscriptions, timers, or event listeners."
Common Use Cases
API calls · Subscriptions · DOM manipulation
- Fetching data
- Setting up subscriptions
- Updating document title
- Adding event listeners
"useEffect is used for API calls, subscriptions, DOM updates, and other side effects that shouldn't run during render."
useLayoutEffect
Synchronous, before browser paint
useLayoutEffect(() => {
// Runs synchronously before paint
// Use for DOM measurements or updates
}, []);
- Runs synchronously after DOM mutations
- Before browser paints
- Can block rendering
"useLayoutEffect runs synchronously before the browser paints, useful for DOM measurements that need to happen before visual updates."
useEffect vs useLayoutEffect
useEffect = async, useLayoutEffect = sync
| Hook | Timing | Use Case |
|---|---|---|
| useEffect | After paint (async) | API calls, subscriptions |
| useLayoutEffect | Before paint (sync) | DOM measurements, prevent flicker |
"useEffect runs asynchronously after paint, while useLayoutEffect runs synchronously before paint for DOM measurements."
When to Use useLayoutEffect
Measure DOM or prevent visual flicker
Use when:
- Measuring DOM elements
- Preventing visual flicker
- Synchronous DOM updates needed
"Use useLayoutEffect when you need to measure DOM elements or prevent visual flicker from layout changes."
9️⃣ Multiple Effects
Separate effects by concern
// Separate concerns
useEffect(() => {
// API call
}, [userId]);
useEffect(() => {
// Document title
}, [title]);
"Separate effects by concern - React can optimize and manage them independently."
Best Practices
✅ Include all dependencies ✅ Clean up subscriptions ✅ Use useLayoutEffect sparingly ✅ Separate effects by concern ❌ Don't forget dependency array ❌ Don't use for derived state
"useEffect handles side effects after render, with a dependency array controlling execution. It supports cleanup functions for subscriptions. useLayoutEffect runs synchronously before paint for DOM measurements. useEffect is async and non-blocking, while useLayoutEffect is sync and can block rendering. Use useEffect for most side effects, useLayoutEffect only when needed for DOM measurements."
🧠 Ultra-Short Cheat Sheet
useEffect (after render, async)
useLayoutEffect (before paint, sync)
Dependency array controls execution
Cleanup function
Separate effects by concern