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

如何在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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:22:54