Yasin

Yasin

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 要放依赖数组

依赖不变 → 返回缓存的旧函数;依赖变了 → 重新创建函数。