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

使用RTK-Query设置React Context值遇问题:数据未加载Context已渲染

问题分析与修复方案

你的代码存在几个关键问题,导致数据未加载完成时Context就完成渲染:

  1. RTK Query Hooks调用位置错误:useFetchMyQuery()作为React Hook,必须直接在组件顶层调用,不能放在useEffect内部——这违反了React Hooks的规则,同时会导致你无法在组件顶层获取isFetching、data等状态,加载判断逻辑完全失效。
  2. 冗余的useState:RTK Query已经内置了数据缓存与状态管理,不需要额外用useState来存储data,额外的状态会导致数据不同步,且初始状态未对齐Context默认值。
  3. 依赖数组错误:useEffect的依赖数组中引用的data、isFetching等变量是在effect内部声明的,组件顶层根本不存在这些变量,这会导致lint报错,且effect逻辑完全无法按预期触发。

修正后的代码

export const defaultContext = {
    header: {},
};
export const MyContext = React.createContext(defaultContext);

export default function Page({ className, children, loadingText }) {
    // 直接在组件顶层调用RTK Query的Hook
    const { data, isFetching, isError } = useFetchMyQuery();

    // 加载状态判断:此时isFetching是实时的RTK Query状态
    if (isFetching) {
        return <Loader message={loadingText} />;
    }

    // 使用RTK Query返回的data作为Context值,若data为undefined则用默认值兜底
    const contextValue = data ?? defaultContext;

    return (
      <DndProvider backend={HTML5Backend}>
        <MyContext.Provider value={contextValue}>
          <div className={`${styles.page} ${className}`}>
            <div className={styles.leftSide} />
            <div className={styles.rightSide} />
            {children}
          </div>
        </MyContext.Provider>
      </DndProvider>
    );
}

关键修改说明

  • 将RTK Query Hook移到组件顶层:这样能直接获取到isFetching、data等实时状态,加载判断逻辑可以正常生效,确保数据加载完成后才渲染Context Provider和子组件。
  • 移除冗余的useState与useEffect:直接使用RTK Query返回的data,避免状态冗余和不同步问题;同时用??运算符兜底,确保Context值始终符合defaultContext的结构,避免子组件消费Context时出现属性undefined的问题。
  • 修正加载判断逻辑:现在isFetching是RTK Query提供的真实加载状态,会在数据请求过程中保持true,直到数据加载完成,此时才会渲染后续的Context和页面内容。

内容的提问来源于stack exchange,提问作者Aleksandar Andrijevic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 14:40:02