useCallback
在 React 中,组件的重新渲染是一个重要的性能考虑因素。随着我们应用程序的复杂性增加,经常因为传递给子组件的函数变更而导致不必要的重新渲染(由于函数变化了,此时就算组件用了 memo
,因为函数实际变化了,这个 memo
就会失效了)。为了避免这种情况,React 提供了一个另一个 Hook 函数 **useCallback
**。它可以缓存函数实例的 React Hook,避免在每次渲染时都重新创建函数,从而提高性能。
基本概念
useCallback
是 React 的一个 Hook,它用于缓存一个函数,只有在依赖项发生变化时,才会返回新的函数实例。这个 Hook 主要用于避免函数的重新创建,特别是在函数作为子组件的 props 或者在依赖项数组中时,能够有效减少不必要的渲染。
基本语法
1 | const memoizedCallback = useCallback( |
使用场景
将函数作为 props 传递给子组件
如果函数频繁地作为 props 传递给子组件,使用
useCallback
可以避免每次父组件渲染时,子组件接收到新的函数引用,避免不必要的渲染。优化依赖关系复杂的
useEffect
和useMemo
在某些场景下,
useEffect
或useMemo
可能依赖于某些函数。使用useCallback
可以确保这些函数不会在每次渲染时创建新的实例,避免了额外的依赖变化,确保渲染的稳定性。
使用示例
避免子组件重新渲染
1 | import React, { useState, useCallback } from 'react'; |
在这个例子中,Child
组件被包裹在 React.memo
中,只有当 onClick
这个 prop 变化时才会重新渲染。这里的 useCallback
确保了 increment
函数只有在 Parent
组件第一次渲染时创建,并且 increment
函数不会在每次 Parent
组件重新渲染时重新创建。这样,Child
组件就不会因为 Parent
渲染而重新渲染,避免了不必要的渲染开销。
在 useEffect
中使用 useCallback
1 | import React, { useState, useEffect, useCallback } from 'react'; |
在这个例子中,fetchData
是一个在 useEffect
中使用的函数。如果不使用 useCallback
,每次 Parent
组件渲染时,fetchData
都会被重新创建,导致 useEffect
重新执行。通过 useCallback
,我们确保 fetchData
只有在第一次渲染时创建,从而避免了 useEffect
的不必要调用。
useCallback
与 memo
使用
useCallback
和 React.memo
常常是配合使用的。useCallback
缓存函数实例,而 React.memo
用于缓存组件的渲染结果。两者结合使用时,可以有效避免函数和组件的无意义渲染,提升性能。
区别
- **
useCallback
**:主要用于缓存函数实例。它返回的是一个函数,该函数只有在其依赖项变化时才会更新。 - **
useMemo
**:主要用于缓存计算结果。它返回的是计算结果,并且只有在其依赖项变化时,才会重新计算值。
两者的核心区别在于:useCallback
是用来缓存函数本身,useMemo
是用来缓存计算结果。
useCallback