Come and join us!
“The Newbies of Little Wo Shan” provides front-end developers with technical information and a series of basic articles. For a better user experience, please go to xhs-rookies.com/ to learn the latest articles.
“Code Tailor “, if you are interested in our article, or would like to make some suggestions, please follow the official account of “Rookie of Xiaohe Mountain” on wechat and contact us. You can also view our article on wechat. Every suggestion or approval is a great encouragement to us!
preface
In this article, our main purpose is to understand the use of useCallback.
useCallback
define
UseCallback returns a Memoized callback function.
const memoizedCallback = useCallback(fn, deps)
Copy the code
Parameter required for useCallback
fn
: a function will eventually return the callback function, which can only be called indeps
Updates only when parameters change.deps
: Used to triggerfn
The list of arguments that the callback function changes.
Note: deps is an array, which means there can be many changes to fn’s parameters.
Passing the inline callback function and the array of dependencies as arguments to useCallback returns the Memoized version of the callback function, which is updated only when a dependency changes. This is useful when you pass callback data to child components that are optimized and use reference equality to avoid unnecessary rendering (such as shouldComponentUpdate).
How to use
Let’s start with a simple example.
This is a child component that takes an FN method of the parent class and displays its button.
const ChildComponent = memo(function (props) {
console.log('child render! ')
return <Button onClick={props.fn}> showTime</Button>
})
Copy the code
Reactjs.org (reactjs.org) reactjs.org (reactjs.org)
This is a parent component that has a counter, a number increment button, and this child component.
function Main() {
const [count, setcount] = useState(0)
const ShowTime = () = > {
console.log('now time :' + new Date()}return (
<Row
style={{
'flex-direction': 'column'}} >
<Col>
<Title>Index: {count}</Title>
</Col>
<Col>
<Button onClick={()= > setcount(count + 1)}>increase</Button>
</Col>
<Col>
<ChildComponent fn={ShowTime} />
</Col>
</Row>)}Copy the code
We can see that the count increases when we click the increase button, which is normal and reasonable.
But if we open up our browser console at this point, we’ll see that the child ChildComponent keeps rendering.
For us, the child component should only be affected by the childname argument. If fn is not changed, we should not render.
Note: The reason why the subcomponent keeps rendering is because the ShowTime method is constantly recreating, which then causes the props to be different for the subcomponent, thus rendering the subcomponent
This is where we use the useCallback.
function Main() {
const [count, setcount] = useState(0)
const useMemoryCallback = useCallback(() = > {
console.log('now time :' + new Date()}, [])return (
<Row
style={{
'flex-direction': 'column',
marginLeft: '10px'}} >
<Col>
<Title>Index: {count}</Title>
</Col>
<Col>
<Button onClick={()= > setcount(count + 1)}>increase</Button>
</Col>
<Col>
<ChildComponent fn={useMemoryCallback} />
</Col>
</Row>)}Copy the code
At this point, we return this function in the useCallback, since the deps parameter is empty, there is no need to change it, so when we click the increase button we will not trigger the render of the child component.
How to check
Dependency arrays (DEPS) are not passed as arguments to callback functions. Conceptually, though, it looks like this: all values referenced in callback functions should appear in dependency arrays. In the future, compilers will get smarter and it will be possible to create arrays automatically.
We recommend enabling the Strict-deps rule in eslint-plugin-react-hooks. This rule warns when you add false dependencies and suggests how to fix them.
summary
useCallback
Which brings us to memory functions, combining subcomponents anduseMemo
It can optimize component loading.- If the child component accepts a method as a property, we are using it
React.memo
This is needed to avoid unnecessary rendering by child componentsuseCallback
Cooperate, or elseReact.memo
Would be meaningless.
Next day forecast
In the next section, we will introduce hook rules, so stay tuned!