useEffect vs useLayoutEffect: When to Use Each Correctly

One of the most confusing parts of working with React Hooks is having two hooks with almost identical syntax: useEffect and useLayoutEffect. Without understanding how they work under the hood, it’s easy to pick the wrong one and accidentally cause flickering or slow down your entire app. This article breaks each hook down so you can make the right call in every situation.

useEffectuseLayoutEffectReact hooksDOM
Cover image: useEffect vs useLayoutEffect: When to Use Each Correctly
Avatar of Trung Vũ Hoàng

Trung Vũ Hoàng

Author

22/3/20265 min read

1. What Are Side Effects in React?

Before we compare them, let’s clarify the notion of Side Effects. These are tasks that occur outside React’s render flow, such as fetching data via APIs, directly manipulating the DOM, or setting up subscriptions to external events.

Both useEffect and useLayoutEffect exist to handle these tasks — the key difference lies in the timing of when they run relative to the browser’s paint cycle.

2. How They Work: Asynchronous vs Synchronous

useEffect — The Performance-Friendly Hook

useEffect is the default choice and suits most cases. The sequence looks like this:

  1. React detects a state change.

  2. React re-renders the component.

  3. The browser paints the updated UI.

  4. useEffect now runs.

Because the callback is invoked after the screen has finished updating, useEffect does not block the browser — keeping the UI responsive and smooth for users.

useLayoutEffect — The Visual-Accuracy-First Hook

By contrast, useLayoutEffect wedges itself in before the browser paints:

  1. React detects a state change.

  2. React re-renders the component.

  3. useLayoutEffect runs immediately (synchronously).

  4. The browser is then allowed to paint.

This means any changes you make inside useLayoutEffect are applied before the user can see any rendered result.

3. Detailed Comparison

Here are the most important criteria to tell these two hooks apart:

Execution timing

  • useEffect: Runs after the browser has painted the UI (After Paint).

  • useLayoutEffect: Runs before the browser paints the UI (Before Paint).

Execution type

  • useEffect: Asynchronous (Async) — does not block rendering.

  • useLayoutEffect: Synchronous (Sync) — blocks rendering until it finishes.

Performance impact

  • useEffect: Friendly to page load speed, no interruptions.

  • useLayoutEffect: Can cause the page to "freeze" if heavy work is done inside.

Typical use cases

  • useEffect: API calls, Analytics, Event listeners — anything that doesn’t need to happen before paint.

  • useLayoutEffect: Measuring DOM size, adjusting element positions — things users must see correctly on the very first frame.

4. When Do You Actually Need useLayoutEffect?

Although React officially recommends prioritizing useEffect, there are situations where useLayoutEffect is the only way to avoid a poor user experience.

Scenario 1: Prevent UI Flicker

Suppose you need to compute the exact position of a Tooltip based on the button’s actual size:

  • With useEffect: The Tooltip appears in its old position → The browser paints → useEffect recalculates → Re-render → The Tooltip "jumps" to the new spot. Users clearly see the jank.

  • With useLayoutEffect: The position is computed before the browser paints. The Tooltip appears in the correct place from the start, with no visible jitter.

Scenario 2: Measuring DOM Size

When using getBoundingClientRect() or other DOM measurement APIs to build complex layouts, useLayoutEffect ensures the values you read reflect the actual DOM state — before users see the final result.

5. Execution Order in Practice

Consider the snippet below to see the priority clearly:

useLayoutEffect(() => {
  console.log("1. useLayoutEffect runs");
}, [count]);

useEffect(() => {
  console.log("2. useEffect runs");
}, [count]);

Whenever count changes, the console always prints 1 before 2 — regardless of the order you declare them in the component. This priority is fixed and guaranteed by React.

6. Golden Rules for Choosing a Hook

From real-world product development: Always start with useEffect. Switch to useLayoutEffect only when you observe flicker or visual misalignment.

Overusing useLayoutEffect undermines React Concurrent Mode’s render optimizations, preventing your app from taking advantage of splitting and prioritizing work per frame.

Note for Next.js and SSR: When working with Server-Side Rendering, avoid using useLayoutEffect at the top-level component because the server has no DOM — this will trigger a build warning and can cause hydration issues.

7. Conclusion

Mastering the difference between useEffect vs useLayoutEffect is a hallmark of a seasoned React developer. A simple rule of thumb:

  • useEffect → Prioritizes performance, runs after paint.

  • useLayoutEffect → Prioritizes visual accuracy, runs before paint.

Understanding this not only helps you ace interview questions but also build truly high-quality React applications.

Found this article helpful?

Contact us for a free consultation about our services

Contact us

Bài viết liên quan