You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义Hook中更新useRef存储的函数对象?

在自定义Hook中更新useRef存储的函数对象

useRef的.current属性是可变的,更新它不需要特殊的setter方法,直接赋值即可。根据使用场景,分两种情况处理:

场景1:同步外部传入的回调函数

如果自定义Hook需要接收外部传入的回调(比如组件调用Hook时传递的onComplete),可以通过useEffect监听回调的变化,同步更新ref:

// 假设自定义Hook接收外部传入的callback参数
const myHook = (callback) => {
  const cbRef = useRef(callback);

  // 监听外部回调变化,同步更新ref
  useEffect(() => {
    cbRef.current = callback;
  }, [callback]); // 依赖项添加callback,确保每次回调更新时同步ref

  // 示例:在副作用中调用最新的回调
  useEffect(() => {
    const handleEvent = () => {
      cbRef.current(); // 始终调用最新的函数版本
    };
    window.addEventListener('resize', handleEvent);
    return () => window.removeEventListener('resize', handleEvent);
  }, []); // 此处依赖项为空,通过ref获取最新函数,避免频繁解绑/绑定事件
};

场景2:Hook内部更新函数

如果函数是Hook内部生成的,直接在需要更新的位置给cbRef.current赋值即可,无需借助useEffect:

const myHook = () => {
  const cbRef = useRef(() => {});
  const [count, setCount] = useState(0);

  // 示例:当count变化时更新ref中的函数
  const updateCallback = () => {
    cbRef.current = () => {
      console.log(`当前count值:${count}`);
    };
  };

  // 调用示例
  useEffect(() => {
    updateCallback();
  }, [count]);

  return { triggerCallback: () => cbRef.current(), count, setCount };
};

关键说明

  • useRef的.current不会触发组件重渲染,适合存储需要在多次渲染间保持引用、且无需触发UI更新的值(比如函数、DOM元素)。
  • 若外部传入的是内联函数(比如父组件中myHook(() => console.log(count))),必须通过useEffect监听回调变化来同步ref,否则ref中会保留旧的函数引用。

内容的提问来源于stack exchange,提问作者Ben Aston

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:43:17