background
First we define a Compound Component:
const App = (a)= > {
console.log('App render.')
const [count, setCount] = useState(0)
const someValue = 'someValue'
return (
<div>
<button onClick={() => setCount(prev=>prev+1)}>
click to rerender
</button>
<CountDemo count={count} />
<Demo someValue={someValue} />
</div>
)
}
Copy the code
The two sub-components are:
const CountDemo = ({count}) = > {
console.log('count render.')
return (
<div>
<p>{count}</p>
</div>)}const Demo = (a)= > {
console.log('Demo render.')
return (
<div>Demo</div>)}Copy the code
When we click the button, the console displays:
"App render."
"count render."
"Demo render."
Copy the code
You can see that both CountDemo and Demo are re-rendered, but in reality, only CountDemo needs to be updated.
memo
React.memo can be used to avoid duplicate rendering of the Demo component:
/ / use the React. Memo
const Demo = memo((a)= > {
console.log('Demo render.')
return (
<div>React.memo</div>)})Copy the code
Click the button, the console displays:
"App render."
"count render."
Copy the code
Avoid unnecessary rerendering of the demo.
useCallback
What if, instead of primitive type data, the child component is passed a function?
const App = (a)= >{... const someValue ='someValue'
const someFunc = (a)= > someValue
...
<Demo someFunc={someFunc} />
...
}
const Demo = memo(({someFunc}) = >{... return (<div>{someFunc()}</div>)})Copy the code
Click the button, the console displays:
"App render."
"count render."
"Demo render."
Copy the code
Because the react. memo uses shallowly compare by default, and the function is referential data, the parent component will generate a different someFunc every time it rerenders, which will cause the demo to rerender. So, you can use useCallback to return a memoized callback:
const App = (a)= >{...// With useCallback, someValue changes when someValue changes
const someFunc = useCallback((a)= > someValue, [someValue])
...
}
Copy the code
Click the button at this point and the Demo component will not be rendered unnecessarily repeatedly.
useMemo
If an object is passed in and the object is a reference, like useCallback, we can use useMemo to avoid unnecessary rerendering:
const App = (a)= >{... const someValue ='someValue'
const someObj = useMemo((a)= > ({ value: someValue }), [someValue])
...
<Demo someFunc={someFunc} />
...
}
const Demo = memo(({someObj}) = >{... return (<div>{someObj.value}</div>)})Copy the code
Online sample
See the Pen React Demo by eehong (@eugene930) on CodePen.
reference
Hooks API Reference
Hooks Cheatshhet