BrowserRouter应置于何处?React/Redux路由应用路径配置疑问
解决React-Router-Redux中添加basename的问题
嘿,我来帮你把这个问题捋清楚!首先要明确两个核心点:BrowserRouter不是可选的,但你之前没用到它也能正常运行,是因为react-router-redux的ConnectedRouter已经充当了路由顶层容器的角色——它本质上是基于react-router的Router组件封装的,自带路由上下文能力。
你之前在ComponentA和ComponentB里分别包裹BrowserRouter是错误的,原因很简单:整个应用只能有一个顶层路由容器,多个独立的BrowserRouter会导致路由上下文冲突,不仅basename无法全局生效,还可能引发其他路由异常。
正确的实现方式(两种可选)
方式1:在创建History实例时设置basename(推荐)
因为你用了react-router-redux,路由状态是和Redux store绑定的,所以最稳妥的方式是在创建history实例时直接指定basename,这样所有路由操作都会自动带上前缀:
// 应用入口文件(比如index.js) import { Provider } from 'react-redux'; import { ConnectedRouter } from 'react-router-redux'; import { createBrowserHistory } from 'history'; import store from './your-redux-store'; import YourRouteComponents from './your-routes'; // 创建带basename的history实例 const history = createBrowserHistory({ basename: '/calendar' }); ReactDOM.render( <Provider store={store}> {/* 用ConnectedRouter作为顶层路由容器 */} <ConnectedRouter history={history}> {/* 所有路由相关组件(NavLink、Switch、Route等)都放在这里面 */} <YourRouteComponents /> </ConnectedRouter> </Provider>, document.getElementById('root') );
这样处理后,你所有的<NavLink to="/today"/>会自动渲染成<a href="/calendar/today">,Route的path也不需要修改——history会自动处理前缀匹配。
方式2:用BrowserRouter包裹ConnectedRouter
如果你更倾向于用BrowserRouter的basename属性,需要把它放在最外层,包裹ConnectedRouter,确保整个应用只有一个路由上下文:
// 应用入口文件 import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; import { ConnectedRouter } from 'react-router-redux'; import { createBrowserHistory } from 'history'; import store from './your-redux-store'; import YourRouteComponents from './your-routes'; const history = createBrowserHistory(); ReactDOM.render( <Provider store={store}> <BrowserRouter basename="/calendar"> <ConnectedRouter history={history}> <YourRouteComponents /> </ConnectedRouter> </BrowserRouter> </Provider>, document.getElementById('root') );
这种方式也能生效,但不如方式1直接,因为react-router-redux的核心是和history实例绑定的。
关键注意事项
- 绝对不要在多个组件里分别包裹
BrowserRouter或ConnectedRouter,必须保证整个应用只有一个顶层路由容器。 - 你的导航组件(NavLink)和路由匹配组件(Switch、Route)都必须放在这个顶层容器内部,才能共享路由上下文和
basename设置。
内容的提问来源于stack exchange,提问作者Fellow Stranger
相关产品推荐
相关产品推荐

