🧭 Introduction
Most React developers use useEffect daily — but very few understand when it runs and why timing matters.
You may have seen:
- UI flickering
- Incorrect element measurements
- Animations jumping
- Layout glitches
And the common (but wrong) solution:
“Let’s try
useLayoutEffecteverywhere.”
❌ That causes performance problems.
In this lesson, you’ll learn:
- The exact timing difference between
useEffectanduseLayoutEffect - When
useLayoutEffectis required - When it is dangerous
- How senior developers decide between them
🎯 What You’ll Learn in This Lesson
By the end of this lesson, you will understand:
- When
useEffectruns in the render cycle - When
useLayoutEffectruns - Visual vs non-visual side effects
- Real-world use cases for each
- Best practices and common mistakes
🔄 The React Rendering Timeline (Critical)
To understand this lesson, you must know this sequence:
1️⃣ React renders component
2️⃣ React commits changes to the DOM
3️⃣ Browser paints UI on screen
4️⃣ useEffect runs
Now compare with useLayoutEffect.
⏱ When useLayoutEffect Runs
useLayoutEffect runs earlier:
1️⃣ React renders component
2️⃣ React commits changes to the DOM
3️⃣ useLayoutEffect runs (before paint)
4️⃣ Browser paints UI
👉 This timing difference is everything.
🧠 Key Difference (One Line Summary)
useEffect runs after paint
useLayoutEffect runs before paint
🧩 useEffect (Default Choice)
useEffect is for:
- Data fetching
- Subscriptions
- Logging
- Non-visual side effects
Example:
useEffect(() => {
fetchData();
}, []);
React paints UI first, then runs the effect.
🧩 useLayoutEffect (Special Case)
useLayoutEffect is for:
- Reading layout values
- Measuring DOM elements
- Applying synchronous layout changes
Example:
useLayoutEffect(() => {
const height = ref.current.offsetHeight;
}, []);
React waits until this effect completes before painting UI.
⚠ Why Blocking Paint Is Dangerous
Because:
- Browser cannot show UI until effect finishes
- Heavy logic blocks rendering
- App feels slow or frozen
👉 That’s why useLayoutEffect must be used sparingly.
🔍 Real-World Example — Measuring DOM (Correct Use)
function Tooltip() {
const ref = useRef();
const [width, setWidth] = useState(0);
useLayoutEffect(() => {
setWidth(ref.current.offsetWidth);
}, []);
return <div ref={ref}>Tooltip width: {width}</div>;
}
Why useLayoutEffect?
- Measurement must happen before paint
- Prevents visible layout jump
🔍 Same Example with useEffect (Problematic)
useEffect(() => {
setWidth(ref.current.offsetWidth);
}, []);
Result:
- UI paints first
- Then width updates
- Causes visual flicker
🎨 Animations & Layout Sync
When:
- Applying animations
- Adjusting position
- Syncing scroll
👉 useLayoutEffect ensures changes happen before user sees UI.
🧠 Decision Rule (Senior-Level Insight)
Use this rule:
❓ Does this effect read or modify layout?
- ❌ No → useEffect
- ✅ Yes → useLayoutEffect
🆚 useEffect vs useLayoutEffect (Quick Table)
| Feature | useEffect | useLayoutEffect |
|---|---|---|
| Runs after paint | ✅ Yes | ❌ No |
| Blocks UI | ❌ No | ✅ Yes |
| Default choice | ✅ Yes | ❌ No |
| Layout measurement | ❌ No | ✅ Yes |
| Performance safe | ✅ Yes | ⚠️ Use carefully |
🚨 Common Mistakes (Very Important)
❌ Mistake 1: Replacing all useEffect with useLayoutEffect
This causes unnecessary UI blocking.
❌ Mistake 2: Doing heavy logic in useLayoutEffect
Never fetch data or run long computations here.
❌ Mistake 3: Using useLayoutEffect without DOM access
If no layout is involved, it’s unnecessary.
🧠 SSR Warning (Advanced Insight)
In Server-Side Rendering (SSR):
useLayoutEffectdoes nothing on server- React shows warnings
Solution:
useEffect(() => {}, []);
Or use an isomorphic layout effect pattern.
🎯 Best Practices
✅ Default to useEffect
✅ Use useLayoutEffect only for layout reads/writes
✅ Keep layout effects short
✅ Never fetch data in useLayoutEffect
❓ FAQs — useLayoutEffect vs useEffect
🔹 Is useLayoutEffect faster?
No. It blocks paint, so it can feel slower.
🔹 Should beginners avoid useLayoutEffect?
Yes — until they understand rendering timing.
🔹 Can I replace animations with CSS instead?
Often yes — CSS animations are better.
🔹 Is useLayoutEffect required often?
No. It’s a niche hook.
🧠 Quick Recap
✔ useEffect runs after paint
✔ useLayoutEffect runs before paint
✔ Layout reads require useLayoutEffect
✔ Blocking paint is expensive
✔ Default to useEffect
🎉 Conclusion
Understanding when effects run changes how you design UI.
From now on:
- You won’t blindly use useLayoutEffect
- You’ll fix layout flickers correctly
- You’ll write smoother, professional UIs
This lesson completes your Advanced Hooks mastery ⚛️🧠
👉 Next Section
SECTION 3 — Custom Hooks Mastery
Lesson 9 — What Makes a Good Custom Hook