Skyroc Admin React
架构

运行时 Provider

理解 App.tsx 的 QueryClient、Jotai、Devtools、AntdProvider、NotificationProvider、LazyAnimate、RouterProvider 和 GlobalEffect 顺序

这一页聚焦 apps/admin/src/App.tsx 的 React 运行时组合。bootstrap.tsx 负责 React 渲染前的一次性初始化,App.tsx 负责 React context、状态容器、UI 运行时、路由和全局 effect 的依赖顺序。

如果只是新增一个启动前运行一次的插件,优先看 启动流程。如果能力需要 React context、hooks、Provider 或组件生命周期,再看这一页。

适用场景

场景重点位置
新增 React Providerapps/admin/src/App.tsx
调整 React Query、Jotai 或 Devtools 关系queryClientglobalStoreAdminDevtools
修改 Ant Design locale、主题或 message APIfeatures/antd/AntdProvider.tsx
修改通知系统能力NotificationProviderwechat-style-notification.wav
修改路由上下文或全局 effectRouterProviderGlobalEffect
排查更新检测、NProgress、Dayjs、Iconifyapps/admin/src/pluginspages/__root.tsx

当前实现位置

文件职责
apps/admin/src/App.tsx组合 React Query、Jotai、Devtools、Ant Design、通知、动画、路由和全局副作用。
apps/admin/src/service/queryClient.ts创建全局 queryClient,开发环境记录 query 和 mutation error。
apps/admin/src/features/antd/AntdProvider.tsx连接 Ant Design locale、主题 token、modal/message/notification 静态 API holder。
apps/admin/src/features/router/RouterProvider.tsx把认证、用户、菜单首页和初始化函数注入 TanStack Router context。
apps/admin/src/features/effects/GlobalEffect.tsx挂载主题 effect 和语言 effect。
apps/admin/src/plugins/index.ts注册 Dayjs、应用更新检测、Iconify 离线服务和 NProgress。
apps/admin/src/pages/__root.tsx根路由中处理 NProgress、auth 初始化、错误页、404 和 pending loading。

Provider 顺序

当前 App.tsx 的组合顺序是:

QueryClientProvider
  -> JotaiProvider
    -> Devtools
    -> AntdProvider
      -> NotificationProvider
        -> LazyAnimate
          -> RouterProvider
          -> GlobalEffect

这不是随意嵌套。每一层都有下游依赖:

依赖或提供能力
QueryClientProvider给认证、路由守卫、服务 hooks、Ant Design provider 等下游代码提供同一个 query client。
JotaiProvider给主题、语言、认证状态、Devtools 等 atom 状态提供 store。
Devtools只在开发环境加载,接入 queryClientrouterglobalStore 和当前主题。
AntdProvider读取语言和主题状态,提供 Ant Design ConfigProvider 以及静态 API holder。
NotificationProvider提供应用内通知上下文,并由 apps/admin 注入通知音效资源。
LazyAnimate给下层路由页面和全局 effect 提供动画运行时。
RouterProvider注入 TanStack Router context,承接页面路由、守卫和布局。
GlobalEffect挂载主题、语言等全局副作用,不渲染业务 UI。

Devtools 的边界

AdminDevtools 只在 import.meta.env.DEV 为真时通过 lazy() 动态加载。生产环境使用空组件替代。

Devtools 当前接收四类运行时对象:

对象来源作用
configglobalConfig.devtools + 当前 darkMode控制 devtools 展示配置和明暗主题。
queryClientapps/admin/src/service/queryClient.ts查看 React Query 缓存和请求状态。
routerapps/admin/src/features/router查看路由信息。
store@skyroc/core-stateglobalStore查看 Jotai 全局 store。

这里的主题配置使用 useSettingsTheme() 读取当前暗色模式。不要把 devtools 主题写死,否则暗色模式切换后调试面板会和应用主题脱节。

React Query 缓存

queryClient 是全局单例。当前 createQueryClient() 给 query 和 mutation 都配置了 onError,但只在开发环境打印错误。

认证链路会直接使用这个 queryClient

位置行为
useAuth().initAuth()ensureQueryData(queryUserInfoOptions()) 拉用户信息,再初始化菜单。
useAuth().clearAuth()queryClient.clear() 清空缓存,避免退出后保留旧用户数据。
根路由 beforeLoad已登录但未初始化时调用 context.initAuth()

如果新增跨页面共享数据,优先进入服务模块的 query hooks,不要在 Provider 里额外创建第二个 query client。

全局插件和 Provider 的区别

不是所有运行时能力都应该放进 App.tsx

类型放置位置示例
React context 或 hooks 能力App.tsxReact Query、Jotai、Ant Design、通知、路由。
渲染前一次性初始化bootstrap.tsxsetupTheme()setupAdminLayouts()setupI18n()
浏览器级运行时副作用plugins/index.tsDayjs、NProgress、Iconify、生产环境更新检测。
页面路由生命周期pages/__root.tsx、layout routeNProgress done/start、登录初始化、权限守卫。

生产环境应用更新检测属于插件。它由 globalConfig.automaticallyDetectUpdateimport.meta.env.PROD 共同控制,检测到新版本后通过 notification 提示用户刷新当前路由。

最小新增 Provider 示例

新增 Provider 时,先判断它需要包住哪些下游能力,再放到最近的依赖位置。下面示例展示一个依赖 React Query 的 Provider 应该放在 QueryClientProvider 内部,而不是外部。

import type { ReactNode } from 'react';

interface AdminRealtimeProviderProps {
  /** 需要接收实时事件上下文的应用内容。 */
  children: ReactNode;
}

const AdminRealtimeProvider = (props: AdminRealtimeProviderProps) => {
  const { children } = props;

  return <RealtimeProvider>{children}</RealtimeProvider>;
};

const Provider = (props: ProviderProps) => {
  const { children } = props;

  return (
    <QueryClientProvider client={queryClient}>
      <JotaiProvider>
        <AdminRealtimeProvider>
          <Devtools />
          {children}
        </AdminRealtimeProvider>
      </JotaiProvider>
    </QueryClientProvider>
  );
};

如果新 Provider 需要 Ant Design 静态 API 或通知 context,就应该放在 AntdProviderNotificationProvider 之下。

常见误区

误区正确做法
bootstrap.tsx 里调用 React hookhook 只能在组件或自定义 hook 中调用,Provider 放 App.tsx
为某个页面单独创建新的 QueryClient复用全局 queryClient,否则缓存和退出清理会分裂。
把更新检测写成 React Provider当前更新检测是浏览器级插件,放在 plugins/app.tsx
在页面里手动同步 Ant Design localeAntdProvider 和 i18n effect 统一处理。
退出登录只删 token还要清 query cache、菜单和 tabs,走 useAuth().clearAuth()

相关链接

On this page