跳到主要内容

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

HookTimingUse Case
useEffectAfter paint (async)API calls, subscriptions
useLayoutEffectBefore 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