useLayoutEffect
Its function signature is the same as useEffect, but it will synchronously call effect after all DOM changes. You can use it to read the DOM layout and trigger re rendering synchronously. Before the browser executes drawing, the update plan inside useLayoutEffect will be refreshed synchronously.
Use standard useEffect whenever possible to avoid blocking visual updates.
For example, if useEffect is used, there will be an obvious flash screen problem
This is used when dealing with dom. When the operation in your useEffect needs to deal with Dom and will change the style of the page, you need to use this. Otherwise, there may be a flash screen problem. The callback function in uselayouteeffect will be executed immediately after the DOM update is completed, but it will be completed before the browser makes any drawing, blocking the drawing of the browser
import React, { useEffect, useLayoutEffect, useState } from "react"; function BoxDemo() { const [currStyle, setCurrStyle] = useState({ width: "100px", height: "100px", backgroundColor: "red", position: "absolute", top: "0px", left: "0px", }); // useLayoutEffect(() => { // setCurrStyle({ // ...currStyle, // position: "absolute", // top: "0px", // left: "100px", // }); // }, []); useEffect(() => { setCurrStyle({ ...currStyle, position: "absolute", top: "0px", left: "100px", }); }, []); const onButtonClick = () => {}; return ( <> <div style={currStyle}>I am box</div> </> ); } export default BoxDemo;
Reference address: https://www.jianshu.com/p/412c874c5add
==============
Use of useMemo
Reproduced in: https://segmentfault.com/a/1190000018697490
Pass the "create" function and dependency array as parameters into useMemo, which recalculates the memoized value only when a dependency changes. This optimization helps to avoid expensive calculations at each rendering.
Let's understand the usage of useMemo through an example.
Parent component
function App() { const [name, setName] = useState("name"); const [content, setContent] = useState("content"); return ( <> <button onClick={() => setName(new Date().getTime())}>name</button> <button onClick={() => setContent(new Date().getTime())}>content</button> <Button name={name}>{content}</Button> </> ); }
Subcomponents
function Button({ name, children }) { function changeName(name) { console.log("11"); return name + "change name Method of"; } const otherName = changeName(name); return ( <> <div>{otherName}</div> <div>{children}</div> </> ); }
Students familiar with react can clearly see that when we click the button of the parent component, the name and children of the child component will change.
Notice that we print console Log method.
Whether we change the value of name or content, we find that the method of changeName will be called.
Does it mean that we only wanted to modify the value of content, but because the name has not changed, we do not need to execute the corresponding changeName method. But it was found that he did. Does this mean the loss of performance and useless work.
Next, we use useMemo for optimization
Optimized sub components
function Button({ name, children }) { function changeName(name) { console.log("11"); return name + "change name Method of"; } const otherName = useMemo(() => changeName(name), [name]); return ( <> <div>{otherName}</div> <div>{children}</div> </> ); } export default Button;
At this time, we click the button to change the content value and find that changeName has not been called.
But when you click the change name value button, changeName is called.
Therefore, we can use useMemo method to avoid calling useless methods. Of course, we may use useState in changename to change the value of state. Does that avoid the secondary rendering of components.
The purpose of optimizing performance is achieved
========================
Use ref to define similar instance variables
In some cases, we need to ensure that after each render of the function component, some variables will not be declared repeatedly, such as Dom node, timer id, etc. in the class component, we can add a user-defined attribute to the class to retain, such as this XXX, but the function component doesn't have this. Naturally, it can't be used in this way. Some friends say that I can use useState to retain the value of the variable, but useState will trigger the component render. It's completely unnecessary here. We need to use useRef to implement it,
When we use ordinary buttons to pause the timer, we find that the timer cannot be cleared, because every time the App component renders, it will reassert timer2, and the timer id is lost in the second render, so we cannot clear the timer. In this case, we need to use useRef to reserve the timer id for us, similar to this XXX, this is another use of useRef.
import React, { useEffect, useCallback, useState, useRef } from "react"; function BoxDemo() { const [count, setCount] = useState(0); const timer = useRef(null); let timer2; useEffect(() => { let id = setInterval(() => { setCount((count) => count + 1); }, 1000); timer.current = id; timer2 = id; return () => { clearInterval(timer.current); }; }); //useCallback(fn, deps) is equivalent to usememo (() = > FN, DEPs). const onClickRef = useCallback(() => { clearInterval(timer.current); }, []); const onClick = useCallback(() => { clearInterval(timer2); }, []); return ( <div> Number of hits: {count} <button onClick={onClick}>ordinary</button> <button onClick={onClickRef}>useRef</button> </div> ); } export default BoxDemo;