preface
React hooks have been using it for almost a year now,useLayoutEffect is sitting there watching like a god, never finding anything to do…
A Layout b Layout C Layout D Layout Does it have to do with manipulating the DOM?
How to use useLayoutEffect is explained in the official document as follows:
UseLayoutEffect has the same function signature as useEffect, but it calls Effect synchronously after all DOM changes. You can use it to read the DOM layout and trigger rerendering synchronously. The update schedule inside useLayoutEffect is refreshed synchronously before the browser performs the drawing.
Use standard Useeffects whenever possible to avoid blocking visual updates.
Tip:
If you are migrating code from a class component to a function component that uses hooks, note that useLayoutEffect is the same as the calling phase for componentDidMount and componentDidUpdate. However, we recommend you start with useEffect and only try use elayouteffect if it goes wrong.
If you use server-side rendering, remember that neither useLayoutEffect nor useEffect can be executed until the Javascript code has loaded. This is why the React alarm is triggered when useLayoutEffect code is introduced into the server rendering component. To solve this problem, either move the code logic to useEffect (if it is not needed for the first rendering) or delay the component until the client finishes rendering (if the HTML is displayed incorrectly until useLayoutEffect is executed).
To exclude components that depend on layout effect from HTML rendered on the server, conditional rendering can be done using showChild &&
Read the official explanation is still a face meng, even a Demo did not give, can only summarize the following two points:
useLayoutEffect
It should be used during synchronous execution, but should not be used to avoid blocking rendering- In the server SSR rendering time, it is best to abandon
useLayoutEffect
useEffect
By default, useEffect should be used. UseEffect combines componentDidMount and componentDidUpdate into one API.
UseEffect is asynchronous, which means using requestIdleCallback to execute incoming callback at idle time in the browser. Most of the time, it doesn’t matter which one you use, if the side effect is long, like a lot of calculations, if it’s useLayoutEffect it will block the rendering.
useLayoutEffect
This is used when working with the DOM. If you want to use an effect that processes the DOM and changes the style of the page, you need to use it. Otherwise, you may have flash screen problems. But it runs before the browser can do any drawing, blocking the browser’s drawing.
Here’s a classic example that everyone uses:
import React, { useEffect, useState, useLayoutEffect, useRef } from 'react';
import { render } from 'react-dom';
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
if (count === 0) {
const randomNum = 10 + Math.random()*200
setCount(10 + Math.random()*200);
}
}, [count]);
return (
<div onClick={() => setCount(0)}>{count}</div>
);
}
render(<App />, document.getElementById('root'));
Copy the code
Can test online stackblitz.com/edit/react-…
When a div is clicked, the page is updated with a random number. When you click continuously, you can see the string of numbers shaking.
The reason is that every time you click on div, count is updated to 0, and then useEffect changes count to a random number.
So the page is rendered to 0 first and then to a random number, and because the update is fast, there is a flicker.
Next we change useEffect to useLayoutEffect:
import React, { useEffect, useState, useLayoutEffect, useRef } from 'react';
import { render } from 'react-dom';
function App() {
const [count, setCount] = useState(0);
useLayoutEffect(() => {
if (count === 0) {
const randomNum = 10 + Math.random()*200
setCount(10 + Math.random()*200);
}
}, [count]);
return (
<div onClick={() => setCount(0)}>{count}</div>
);
}
render(<App />, document.getElementById('root'));
Copy the code
Can test online stackblitz.com/edit/react-…
Instead of using useEffect, when you click on div and count is updated to 0, the page is not rendered. Instead, it waits for the internal state of useLayoutEffect to change before updating the page, so the page does not blink.
Conclusion:
useLayoutEffect
Compared with theuseEffect
The page flicker problem in some feature scenarios can be solved by synchronizing status updates.useEffect
Can fit most scenarios, anduseLayoutEffect
Blocks rendering, so use with caution.
Reference document: Uselayouteffect
When to useLayoutEffect Instead of useEffect
Cloud.tencent.com/developer/a…