React如何在组件外部使用router(或navigate)进行跳转?

1,195 阅读1分钟

方法一:history库 (react-router v5 及以下)

npm i history

创建history.js文件:

import { createHashHistory, createBrowserHistory } from 'history'

const history = createHashHistory() // 或者 createBrowserHistory()

export default history

组件外的js:

import history from '@/components/history'

...
history.push('/web/company/trademgr/tradeprofitmgr')

注:经测试第三方库history这种方法只适用于react-router v5及以下,react-router v6 无效

方法二:react-router v6 配置式路由

如果你的项目是 react-router v6 的,并且是配置式路由的,可以直接用 react-rotuer 提供的 createHashRouter/createBrowserRouter

routes.ts文件:

const routes: RouteObject[] = [
  { path: '', element: <Navigate to="/web/index" replace={true} /> },
  {
    path: '/login',
    lazy: async () => ({ Component: (await import('@/pages/login')).default }),
  },
  {
    path: '/',
    element: <SecurityLayout />,
    children: [
      {
        element: <BasicLayout />,
        children: [
          // 首页
          {
            path: '/web/company/index',
            lazy: async () => ({ Component: (await import('@/pages/home')).default }),
          },
          // 商品管理
          {
            path: '/web/company/goods/goodsmgr',
            lazy: async () => ({ Component: (await import('@/pages/goods/goodsMng')).default }),
          },
        ],
      },
    ],
  },
]

export default routes

export const router = createHashRouter(routes as any)

组件外js文件直接引用这个router就行:

import { router } from '@/routes.ts'

...
router.navigate(`/web/company/goods/goodsmgr`)

附: react-router v6 配置式路由的配置方式

方式三:react-router v6 约定式路由

如果你的项目是约定式路由,无法通过createHashRouter拿到router,我这里的解决思路就是,在被<Router>包裹的最外层组件中拿到 const navigate = useNavigate(),然后把 navigate 挂在window上,这样全局就可以调用了

代码如下

创建一个useGlobalRouter.js:

import { useNavigate } from 'react-router-dom'

export default function useGlobalRouter() {
  const navigate = useNavigate()

  if (!window.__globalRouter) {
    window.__globalRouter = {
      navigate,
    }
  }
}

在最外层组件中(这里是App.js):

import Index from './index'
import Detail from './detail'
import { Routes, Route, Link } from 'react-router-dom'

function App() {
  useGlobalRouter()

  return (
    <div>
      <Routes>
        <Route path="/" element={<Index />}></Route>
        <Route path="/detail" element={<Detail />}></Route>
      </Routes>
    </div>
  )
}

export default App

在组件外js文件:

...
window.__globalRouter.navigate(`/web/company/goods/goodsmgr`)