useCallback获取的Context未更新,如何获取最新Context值?
解决Context更新后
getRequestContext获取旧值的问题 问题出在useCallback对context的捕获机制:如果context是引用类型(比如对象),当它内部属性更新但自身引用未改变时,useCallback不会重新生成函数,导致函数里始终用的是最初捕获的旧context;即使context引用变化,若getRequestContext被外部组件缓存,也可能拿到旧的函数实例。
直接修改代码,用useRef保存最新的context引用,就能确保每次调用getRequestContext都拿到最新值:
export function useData() { const context = useContext(dataStateContext); const contextRef = useRef(context); // 每次context更新时同步ref的指向 useEffect(() => { contextRef.current = context; }, [context]); if (context === undefined) { throw new Error("useData must be used within a dataProvider"); } const getRequestContext = useCallback(async () => { // 读取ref里的最新context const currentContext = contextRef.current; return { headers: currentContext.headers, env: currentContext.env, id: currentContext.id ?? "" }; }, []); // 依赖为空,避免函数频繁重建 return { getRequestContext, }; }
原理说明
useRef的current属性是可变容器,不会触发组件重渲染。我们通过useEffect监听context的变化,一旦context更新就同步更新contextRef.current,保证它始终指向最新的Context实例。useCallback的依赖数组设为空,让getRequestContext的引用保持稳定(不会因为context变化而频繁重建),但每次调用函数时都会读取contextRef.current,自然就能拿到最新的Context属性。
如果你的Context更新方式是每次生成新的对象引用(比如用useState管理,更新时setContext新对象),原来的代码其实可以正常工作,但用useRef的方案能兼容所有Context更新场景,彻底解决旧值问题。
内容的提问来源于stack exchange,提问作者Kalimantan
相关产品推荐
相关产品推荐

