React useCallback的作用
useCallback 是 React 的 hook,用于缓存函数引用,避免每次渲染时创建新的函数实例。
问题背景
React 组件每次渲染时,内部定义的函数都会被重新创建,产生新的引用:
// 每次渲染都是全新的函数,引用不同
const handleClick = () => {
router.push("/login");
};
useCallback 的作用
const handleAuthClick = useCallback(() => {
const redirect = redirectRef.current || "/chat";
router.push(`/login?redirect=${encodeURIComponent(redirect)}`);
}, [router]); // 依赖项:只有 router 变化时才重新创建
只要 router 没有变化,每次渲染返回的都是同一个函数引用。
为什么要缓存函数引用
场景一:作为 useEffect 的依赖
// handleAuthClick 作为依赖传入 useEffect
useEffect(() => {
activityBar.addItem({
onClick: handleAuthClick, // ← 依赖它
});
}, [activityBar, handleAuthClick, status]); // ← 依赖数组里有它
如果 handleAuthClick 没有 useCallback,每次渲染都是新函数 → effect 每次都重新执行 → 可能导致无限循环或重复注册。
场景二:传给子组件避免不必要重渲染
<ChildComponent onClick={handleAuthClick} />
// 如果 handleAuthClick 每次都是新引用,子组件每次都会重渲染
// 用 useCallback 缓存后,引用稳定,子组件不会无谓重渲染
依赖数组规则
和 useEffect 一样,函数内部用到的外部变量都要放进依赖数组:
const handleAuthClick = useCallback(() => {
router.push(...) // 用到了 router
}, [router]); // 所以 router 要放依赖数组
依赖不变 → 返回缓存的旧函数;依赖变了 → 重新创建函数。
