如何在自定义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
相关产品推荐
相关产品推荐

