The useCallback
hook lets us memoize functions. The return value will be the same function (comparable with ===
) for the lifecycle of the component, unless the dependencies array changes. If the dependencies change, then a new function is returned.
This can be useful for 2 reasons:
- As a performance optimization, by preventing unnecessary re-renders when used with memo
- Using a function as a dependency for another hook, since elements in the dependency array are compared with ===
In this example, we count the number of times our Logger
component runs. Since Logger
is wrapped with memo
, it'll only run when its props change. In the normalFunction
case, the function changes every time we press the button. In the memoizedFunction
case, we reuse the same function for 5 button presses, since our count5
variable returns the same value 5 times in a row.
import React, { memo, useCallback, useState } from 'react'
const Logger = memo((props) => {
props.log()
return null
})
export default function App() {
const [count, setCount] = useState(0)
const count5 = Math.floor(count / 5)
const memoizedFunction = useCallback(() => {
console.log('useCallback')
}, [count5])
const normalFunction = () => {
console.log('normal')
}
return (
<>
<button
onClick={() => {
setCount(count + 1)
}}
>
Increment {count}
</button>
<Logger log={memoizedFunction} />
<Logger log={normalFunction} />
</>
)
}