ecnatsiDehTog
ecnatsiDehTog

Reputation: 39

When will the useLayoutEffect hook callback be triggered?

I have an question about when will the useLayoutEffect callback be triggered and when will the screen be drawn.

Consider the following code:

export default function CompA() {
  const [count, setCount] = useState(0);

  useLayoutEffect(() => {
    // I'll debug here after initial render 
    console.log('CompA layoutEffectCallback');
  });

  useEffect(() => {
    console.log('CompA updateEffectCallback');
  }, [count]);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <div onClick={handleClick}>
      CompA
      <h1>{count}</h1>
    </div>
  );
}

After the initial render, the screen displays the number 0,then I set a chrome devtool debugger in the callback of the useLayoutEffect hook before I click the div. After click, the function execution is paused at debugger, but I see the screen already shown number 1.

The docs said that useLayoutEffect fires before the browser repaints the screen,but I don't understand why the screen has updated.

screenshot

Upvotes: 3

Views: 94

Answers (2)

Drew Reese
Drew Reese

Reputation: 202872

Pausing/break-pointing in the useLayoutEffect callback doesn't prevent/block the browser from repainting. It's merely a place you can "hook" into and apply some logic like measuring the computed DOM before the browser repaints. You will still see the updated DOM and repainted view regardless.

Here's a handy, albeit a bit outdated, diagram of the React component lifecycle:

enter image description here

useLayoutEffect is called in roughly the "pre-commit phase" where it can check the computed DOM. useEffect would be called later/after the "commit phase".

Upvotes: 2

JayDev95
JayDev95

Reputation: 1104

The useLayoutEffect hook runs synchronously after the DOM is updated but before the browser repaints.

Initially, you rendered CompA, and the initial state of count was 0. Then, you clicked the div and count was increased to 1.

Since useLayoutEffect is ran after the DOM has been updated BUT before it repaints, the layout effect will log CompA layoutEffectCallback right before the browser performs the paint. This is why you see the screen showing "1" even when the debugger is paused in useLayoutEffect. The DOM has already been updated with the new state before the browser is notified to render it.

Upvotes: -1

Related Questions