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

React Router 6.4.3中createBrowserRouter报错:useNavigate需在Router上下文使用

React Router 6.4.3 切换到 createBrowserRouter 时 useNavigate 上下文错误

问题现象

从 BrowserRouter 切换为 createBrowserRouter 后,出现以下错误:

useNavigate() may be used only in the context of a component.

错误触发自 AuthProvider 组件,该组件内部调用了 useNavigate,但当前组件层级中 AuthProvider 位于 RouterProvider 之外,无法获取路由上下文。

核心原因

当前代码结构中,AuthProvider 在 index.tsx 里作为 App 的父组件渲染,而 RouterProvider 是在 App 内部渲染的。这导致 AuthProvider 初始化时,路由上下文还未被创建,useNavigate 无法拿到所需的路由实例。

解决方案

方案一:将 AuthProvider 整合到路由配置中(推荐)

把 AuthProvider 作为根路由的元素,让所有子路由都处于其包裹下,同时确保它在路由上下文范围内:

  1. 修改 App.tsx 的路由配置
const router = createBrowserRouter([
  {
    element: <AuthProvider />,
    children: [
      {
        element: <ProtectedRoute />,
        children: [
          {
            path: '/',
            element: <DashboardLayout />,
            children: [
              {
                index: true,
                element: <HomePage />,
              },
              {
                path: 'about',
                element: <AboutPage />,
              },
            ],
          },
        ],
      },
      {
        path: '/auth',
        element: <Auth />,
      },
    ],
  },
]);

const App = () => {
  const { isLoading } = useAuth0();

  if (isLoading) {
    return <LoaderPage />;
  }

  return (
    <>
      <Box>
        <CssBaseline />
        <RouterProvider router={router} />
      </Box>
    </>
  );
};
  1. 调整 index.tsx 层级
    移除 index.tsx 中的 AuthProvider,由路由配置负责渲染:
const container = document.getElementById('root')!;
const root = createRoot(container);

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <App />
      </ThemeProvider>
    </Provider>
  </React.StrictMode>
);

方案二:将 RouterProvider 提到 index.tsx 外层

如果不想修改路由结构,可把 RouterProvider 移到 index.tsx 中,确保 AuthProvider 处于路由上下文内:

  1. 拆分路由配置到单独文件(如 router.tsx)
export const router = createBrowserRouter([
  {
    element: <ProtectedRoute />,
    children: [
      {
        path: '/',
        element: <DashboardLayout />,
        children: [
          {
            index: true,
            element: <HomePage />,
          },
          {
            path: 'about',
            element: <AboutPage />,
          },
        ],
      },
    ],
  },
  {
    path: '/auth',
    element: <Auth />,
  },
]);
  1. 修改 index.tsx
import { router } from './router';

const container = document.getElementById('root')!;
const root = createRoot(container);

root.render(
  <React.StrictMode>
    <Provider store={store}>
      <RouterProvider router={router}>
        <AuthProvider>
          <ThemeProvider theme={theme}>
            <App />
          </ThemeProvider>
        </AuthProvider>
      </RouterProvider>
    </Provider>
  </React.StrictMode>
);
  1. 简化 App.tsx
    移除内部路由配置,直接用 Outlet 渲染路由内容:
const App = () => {
  const { isLoading } = useAuth0();

  if (isLoading) {
    return <LoaderPage />;
  }

  return (
    <>
      <Box>
        <CssBaseline />
        <Outlet />
      </Box>
    </>
  );
};

原理说明

useNavigate、useLocation 等 React Router Hooks 必须在 RouterProvider(或传统 BrowserRouter)提供的上下文环境中使用。调整组件层级后,AuthProvider 会在路由上下文初始化完成后渲染,此时调用 useNavigate 就能正常获取路由实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:01:02