React. Usage of memo, useMemo and useCallback these three API s are usually used when optimizing components, and their principle is similar to the caching mechanism of vue's calculation attributes. The dependencies have not changed, and the results obtained before will not be executed in the function; It can also be said that it is based on the principle of memory function. Memory function: that is, if the current input parameter has obtained the result before, it will not be executed again, but directly output the previous result
Look at the code first
As long as any state of the parent component is updated, the component function will be re rendered, resulting in the sub component son being re rendered
Even if the child component does not depend on the state of the parent component
import { useState, memo, useCallback, useMemo } from 'react' const Son = ({ count}: { count: number}) => { console.log('son The component was executed') return <div>son assembly,count: {count}</div> } const PraUseMemo = () => { const [count, setCount] = useState(0) const [num, setNum] = useState(0) return ( <> <div>PraUseMemo</div> <button onClick={() => setCount(count + 1)}>count + 1</button> <button onClick={() => setNum(num + 1)}>num + 1</button> <Son count={count}/> </> ) } export default PraUseMemo
Whether num or count changes, the sub component Son will be executed again. Obviously, this is unreasonable, because the sub component only depends on the count state of the parent component. When the count changes, the sub component will be re rendered
Improvement: use react Memo package subassembly; In this way, only when the count state changes will the sub components be re rendered
import { useState, memo, useCallback, useMemo } from 'react' const Son = memo(({ count, test, total }: { count: number; test: () => void; total: number }) => { console.log('son The component was executed') return <div>son assembly,count: {count}</div> })
Disadvantages: if props passes in a function, react Memo will not work
Reason: each time the parent component re renders, it will execute the const test function expression declaration. Because the function is a reference type, the test variable saves the memory address in the stack. Each const test will open up a new memory space in the heap memory to store the function, and a new memory address in the stack will point to the memory space, Because the memory addresses are different, the test function is considered updated
Improvement: using useCallbck, the first parameter is a function, the second parameter is a dependency (array), and the first parameter (function) is returned, but this function will only be updated when the dependency is updated (that is, the memory address is updated)
import { useState, memo, useCallback, useMemo } from 'react' const Son = memo(({ count, test}: { count: number; test: () => void;}) => { console.log('son The component was executed') return <div>son assembly,count: {count}</div> }) const PraUseMemo = () => { const [count, setCount] = useState(0) const [num, setNum] = useState(0) const test = useCallback(() => { console.log(count) }, [count]) return ( <> <div>PraUseMemo</div> <button onClick={() => setCount(count + 1)}>count + 1</button> <button onClick={() => setNum(num + 1)}>num + 1</button> <Son count={count} test={test} /> </> ) } export default PraUseMemo
Improvement: the first parameter of useMemo is a function that returns a state, and the second parameter is a dependency. Only when the dependency changes, this function will execute and return a new state, similar to the calculation attribute of vue
Parent component const [num, setNum] = useState(0) const total = useMemo(() => 10 + num, [num])
Subcomponents <Son total={total} />
When num does not change, the first parameter function of useMemo will not be executed, total will not be updated, and the sub components will not be re rendered