useCallback
的依赖数组是控制函数缓存是否更新的关键,它决定了何时需要重新创建被缓存的函数。
依赖数组的作用
依赖数组是 useCallback
的第二个参数(一个数组),当数组中的元素发生变化时,useCallback
会返回一个新的函数实例;反之,若数组中的元素没有变化,则返回之前缓存的函数引用。
具体规则
- 空依赖数组
[]
表示函数没有依赖任何外部变量,只会在组件首次渲染时创建一次,之后无论组件如何重渲染,都会返回同一个函数引用:
const handleClick = useCallback(() => {
console.log('初始化后固定不变的函数');
}, []); // 空依赖 → 函数永久缓存
- 包含依赖项的数组
[a, b, ...]
数组中包含函数内部使用的所有外部变量(如 props、state、组件内定义的变量等)。只有当这些依赖项中有任意一个发生变化时,useCallback
才会重新创建函数:
const [count, setCount] = useState(0);
const [name, setName] = useState('');
// 依赖 count,只有 count 变化时函数才会更新
const logCount = useCallback(() => {
console.log('Count:', count); // 使用了外部变量 count
}, [count]); // 依赖数组仅包含 count
- 不传递依赖数组
此时useCallback
不会缓存函数,每次组件重渲染都会返回新的函数实例(相当于没有使用useCallback
)。
为什么必须正确设置依赖?
如果依赖数组遗漏了函数内部使用的变量,会导致闭包陷阱:函数会捕获旧的变量值,而不是最新的值。
例如,下面的代码遗漏了 count
依赖,点击按钮时始终会打印初始值 0
:
const [count, setCount] = useState(0);
// 错误:依赖数组遗漏了 count
const logCount = useCallback(() => {
console.log('Count:', count); // 始终打印 0
}, []); // 错误的依赖设置
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<button onClick={logCount}>Log Count</button>
</div>
);
总结
- 依赖数组是
useCallback
缓存逻辑的核心,决定函数是否需要重新创建 - 必须包含函数内部使用的所有外部变量(props、state 等)
- 空数组
[]
表示函数永久缓存,不依赖任何外部变量 - 错误的依赖设置会导致闭包陷阱,获取不到最新的变量值
可以借助 ESLint 的 react-hooks/exhaustive-deps
规则自动检测依赖是否完整,避免手动设置错误。