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

React应用报错:useLocation()仅能在<Router>组件上下文中使用

问题描述

我开发了一个在Storybook中可正常运行的组件,并发布到私有仓库。但在主项目中引入这个使用<NavLink>的导航组件时,触发错误:

Uncaught Error: useLocation() may be used only in the context of a <Router> component

搜索到的解决方案都是要求用<BrowserRouter>包裹应用,但我的主项目已经用该组件完成了包裹,错误仍然存在,希望得到解决思路。

Index文件

import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import ReactDOM from 'react-dom/client';
import App from './components/Container/App';
import store from './app/store';
import { Provider } from 'react-redux';

const root = ReactDOM.createRoot(document.getElementById('root') || new DocumentFragment());
root.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>
);

App文件

import React from 'react';
import { Routes, Route } from 'react-router-dom';
import PageLayout from '../UI/PageLayout/PageLayout';
import Home from '../Home/Home';
import Portal from '../Portal/Portal';
import ProductSearch from '../ProductSearch/ProductSearch';
import { InternalRoutes } from '../../common/enums/internal-routes';
import Inbox from '../Inbox/Inbox';

const App = () => {
  return (
    <PageLayout >
      <Routes>
        <Route path={InternalRoutes.Default} element={<Home />} />
        <Route path={InternalRoutes.Home} element={<Home />} />
        <Route path={InternalRoutes.Inbox} element={<Inbox />} />
        <Route path={InternalRoutes.Portal} element={<Portal />} />
        <Route path={InternalRoutes.ProductSearch} element={<ProductSearch />} />
      </Routes>             
    </PageLayout>
  );
};

export default App;

PageLayout文件

import React, { FC, ReactNode } from 'react';
import { Logo, PrimaryNavigation } from 'my-component-lib';
import { InternalRoutes as Routes } from '../../../common/enums/internal-routes';

interface I_PageLayoutProps {
  children: ReactNode;
}

const PageLayout:FC<I_PageLayoutProps> = ({children}) => {
  return (
    <div className="body_grid">
      <header>
        <Logo />
        <PrimaryNavigation navigationLinks={Object.values(Routes) as unknown as Array<keyof typeof Routes>} />
      </header>
      <div className={'main_Grid'} >{children}</div>
    </div>
  );
};

export default PageLayout;
解决思路

1. 统一react-router-dom版本

组件库和主项目的react-router-dom版本不一致会导致上下文无法共享:

  • 检查组件库和主项目的package.json,确保两者使用完全相同版本的react-router-dom;
  • 在组件库的package.json中,将react-router-dom、react、react-dom声明为peerDependencies,避免组件库打包时将这些依赖包含进去,强制使用主项目提供的版本。

2. 排查重复依赖实例

如果主项目中存在多个react-router-dom实例,会导致Router上下文隔离:

  • 在主项目和组件库的代码中分别添加console.log(require.resolve('react-router-dom')),打印依赖的实际路径;
  • 若路径不一致,说明存在重复实例,可通过以下方式修复:
    • 删除主项目和组件库的node_modules,重新安装;
    • 使用npm overrides或yarn resolutions,强制项目所有依赖使用同一个react-router-dom版本。

3. 检查组件库打包配置

确保组件库的打包工具(如Rollup、Webpack)将react-router-dom设为外部依赖:

  • 在Rollup配置中,添加external: ['react-router-dom', 'react', 'react-dom'];
  • 在Webpack配置中,设置externals: { 'react-router-dom': 'react-router-dom', react: 'React', 'react-dom': 'ReactDOM' };
  • 这样组件库会使用主项目提供的react-router-dom实例,而不是自带的副本。

4. 验证组件库的Router上下文依赖

虽然Storybook中组件正常运行(因为Storybook可能添加了Router装饰器),但需确认组件库中的PrimaryNavigation组件是否正确依赖外部传入的Router上下文,而非在内部错误地创建了独立的Router实例。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:50:26