To learn useMemo, you must know React.memo
Both of these have some optimization effects
The role of the memo
When the data changes, the code is executed again, but the child component is executed without changing the data. In this case, you can use memo to wrap the child component so that the data is executed only when the data changes
case
Click the button to change the value of n without changing m, and verify that the program will execute m’s code
Not using memo
When n is changed, m is not changed, but Child’s print statement is executed
function App(){
const [n,setN] = useState(0);
const [m,setM] = useState(0);
const add=() = >{
setN(i= >i+1);
};
const addChild=() = >{
setM(i= >i+1);
};
return(
<div>
<div>
n:{n}
<button onClick={add}>n+1</button>
<button onClick={addChild}>m+1</button>
</div>
<Child data={m} />
</div>)}function Child(props){
console.log('Child executed')
return(
<div>
child:{props.data}
</div>
)
}
ReactDOM.render(<App />.document.getElementById('root'));
Copy the code
Use memo for encapsulation
If m does not change, then the Child component will not execute. If m does not change, then the Child component will not execute
Using the React. Memo wrapper returns a new component and calls the new component
function Child(props){
console.log('Child executed')
return(
<div>
child:{props.data}
</div>)}/ / encapsulates the child
const Child2 = React.memo(Child)
ReactDOM.render(<App />.document.getElementById('root'));
Copy the code
If you add a listener function to the Child, it will execute the Child regardless of whether m is changed or not
function App(){
const [n,setN] = useState(0);
const [m,setM] = useState(0);
const add=() = >{
setN(i= >i+1);
};
const addChild=() = >{
setM(i= >i+1);
};
+ const onClickChild=() = >{};return(
<div>
<div>
n:{n}
<button onClick={add}>n+1</button>
<button onClick={addChild}>m+1</button>
</div>
+ <Child2 data={m} onClick={onClickChild} />
</div>)}function Child(props){
console.log('Child executed')
console.log('There's a lot of code here.')
return(+<div onClick={props.onClick}>
child:{props.data}
</div>)}const Child2 = React.memo(Child)
Copy the code
When n is clicked, the App code is reexecuted and the address of the empty onClickChild function is changed, so the Child is still executed
And that’s what useMemo does
The role of useMemo
To solve the problem of rendering yourself due to function updates, you can use useMemo, which rewraps functions
Const onClickChild=useMemo(fn,array) listens to variables. The first argument is a function and the second argument is a dependency. The function is recalculated only if the dependency changes
import React, { useMemo, useState } from 'react'
import ReactDOM from 'react-dom'
// The rest of the code is unchanged, just rewrite the click function of m
// Use useMemo to rewrite the listener function so that it executes only when m changes
const onClickChild=useMemo(() = >{
return () = >{
console.log(m)
}
},[m])
Copy the code
You can also replace useMemo with useCallback, using useCallback without writing a return function
const onClickChild=useMemo(() = >{
return () = >{
console.log(m)
}
},[m])
/ / equivalent to the
const onClickChild=useCallback(() = >{
console.log(m)
},[m])
Copy the code
Note:
- If your value is a function, then you have to write
useMemo(()=>(x)=> console.log(x))
- This is a function that returns a function, which is complicated; So there you have it
useCallback
, you can useuseCallback