useCallback 接受一个函数并返回它的 memoized
版本,也就是缓存该函数。
在 React 的函数式组件中,每次 UI 变化该函数就会重新执行。所以在函数式组件内部定义的函数是不会重复利用的,而是每次都会创建一个新的。创建一个新的函数后,在使用这个函数的组件也会接受一个新的函数,相当于接受的 props
更新了, 所以就需要重新渲染。
例如:
const AddButton = () => {
const [count, setCount] = useState(0);
const handleClick = () => setCount(count + 1);
return <button onClick={handleClick}>{count}</button>
}
在 button 的 props 中我们传入了 handlkeClick
,每次 UI 变化时 AddButton 这个组件就会重新执行一遍,然后重新创建一个 handleClick 函数,button 接受了新的 handleClick 函数就会重新渲染。
因此我们需要仅在 count
发生变化的时候才返回新的 handleClick 函数。这就是 useCallback
的作用。
useCallback 的函数签名如下:
useCallback(fn, deps)
fn 为我们定义的函数,deps 为依赖项数组,只有当这个数组中的变量变化了,fn 才会返回新的函数。依赖项数组类似于 useEffect
。
useCallback 其实并没有避免重复创建函数,因为在 useCallback(fn, [deps]) 的形式中,每次运行都会创建一个函数。useCallback 只是可以决定是不是要使用新的函数。在 依赖项不变的时候,就始终返回之前的,从而避免组件的重复渲染。
如果你确定组件重复渲染问题不大,那么 useCallback 用不用就问题不大。不过最佳实践是使用它处理内部定义的函数。