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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:25:14