首页 > 解决方案 > 反应路由器 v6 在组件之外导航

问题描述

在 react-router v5 中,我创建了这样的历史对象:

import { createBrowserHistory } from "history";
export const history = createBrowserHistory();

然后将其传递给路由器:

import { Router, Switch, Route, Link } from "react-router-dom";
<Router history={history}>
 ... my routes
</Router>

我这样做是为了有机会了解组件之外的使用历史:

   // store action
    logout() {
        this.user = null;
        history.push('/');
    }

通过这种方式,我将逻辑移到了 store 中,并且组件尽可能保持干净。但是现在,在反应路由器 v6 中我不能做同样的事情。我仍然可以useNavigate()在我的组件内部导航,但我无法创建一个navigate将其用于我的商店。有没有其他选择?

标签: javascriptreactjsreact-routerreact-router-dom

解决方案


好吧,事实证明,如果您实现一个自定义路由器,该路由器以与 RRDv6 路由器相同的方式实例化历史状态,那么您可以复制该行为。

检查BrowserRouter的实现,例如:

export function BrowserRouter({
  basename,
  children,
  window
}: BrowserRouterProps) {
  let historyRef = React.useRef<BrowserHistory>();
  if (historyRef.current == null) {
    historyRef.current = createBrowserHistory({ window });
  }

  let history = historyRef.current;
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location
  });

  React.useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      basename={basename}
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
}

创建一个CustomRouter使用自定义history对象并管理状态的:

const CustomRouter = ({ history, ...props }) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      {...props}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
};

history这有效地将自定义对象代理到Router并管理导航状态。

从这里你可以CustomRouter用自定义history对象交换现有的Routerreact-router-dom.

export default function App() {
  return (
    <CustomRouter  history={history}>
      <div className="App">
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/profile" element={<Profile />} />
        </Routes>
      </div>
    </CustomRouter>
  );
}

您的代码和框的分支:

编辑 react-router-v6-navigate-outside-of-components


推荐阅读