如何在react-router-dom v6.9中定义hashbang(#!)片段路由?
在React Router v6.9中实现Hashbang(#!)路由
React Router v6.9移除了v5中HashRouter的hashType配置项,默认只支持普通hash(#)。要实现hashbang(#!)路由,需要通过自定义路由逻辑来处理hash的解析和生成,下面是两种可行的方案:
方法一:自定义Hashbang路由实例
直接基于createHashRouter封装,重写路由的导航和状态解析逻辑,强制使用#!格式的hash:
import { createHashRouter, RouterProvider } from 'react-router-dom'; // 创建支持hashbang的路由实例 function createHashbangRouter(routes) { const router = createHashRouter(routes); // 重写navigate方法,跳转时生成#!开头的hash const originalNavigate = router.navigate; router.navigate = (to, options) => { if (typeof to === 'string') { const hashPath = to.startsWith('/') ? to : `/${to}`; window.location.hash = `!${hashPath}`; return; } originalNavigate(to, options); }; // 重写状态获取逻辑,解析#!后的路径作为路由pathname Object.defineProperty(router, 'state', { get() { const hash = window.location.hash.slice(1); const pathname = hash.startsWith('!') ? hash.slice(1) : hash; const originalState = router._internalRouter.state; return { ...originalState, location: { ...originalState.location, pathname } }; }, }); return router; } // 定义路由规则 const routes = [ { path: '/search', element: <Search /> }, { path: '/configuration', element: <ConfigPage /> }, ]; // 生成路由实例并使用 const router = createHashbangRouter(routes); function App() { return <RouterProvider router={router} />; }
方法二:结合BrowserRouter手动处理Hashbang
如果更倾向于使用BrowserRouter,可以通过监听hash变化、自定义导航函数来实现hashbang逻辑:
import { BrowserRouter, Routes, Route, useNavigate, useEffect } from 'react-router-dom'; // 封装Hashbang处理逻辑组件 function HashbangHandler() { const navigate = useNavigate(); useEffect(() => { // 解析hashbang并同步路由状态 const syncRouteWithHashbang = () => { const hash = window.location.hash.slice(1); if (hash.startsWith('!')) { const targetPath = hash.slice(1); navigate(targetPath, { replace: true }); } }; // 页面加载时初始化一次 syncRouteWithHashbang(); // 监听hash变化 window.addEventListener('hashchange', syncRouteWithHashbang); return () => window.removeEventListener('hashchange', syncRouteWithHashbang); }, [navigate]); // 全局自定义导航函数,生成#!格式的hash window.goToPath = (path) => { window.location.hash = `!${path}`; }; return null; } // 应用组件中使用 function App() { return ( <BrowserRouter basename="/webresources/test_/search"> <HashbangHandler /> <Routes> <Route path="/search" element={<Search />} /> <Route path="/configuration" element={<ConfigPage />} /> </Routes> </BrowserRouter> ); }
注意事项
- 所有页面内跳转都要使用自定义的导航方法(方法一中的
router.navigate或方法二中的window.goToPath),避免直接使用react-router的useNavigate生成普通hash路径。 - 外部链接或手动修改地址栏时,要确保路径格式为
#!/{path},否则路由无法正确识别。 - 测试时要覆盖刷新、前进后退等场景,确保路由状态正常同步。
内容的提问来源于stack exchange,提问作者Charley L.
相关产品推荐
相关产品推荐

