首页 > 解决方案 > 如何检测来自外部组件的匹配路由使用 react-router 匹配的组件?

问题描述

我的 React 应用程序中有以下结构,使用react-router-dom.

<Router>
  <Header/>
  <Main>
    <AllRoutes>      // THIS HANDLES THE SWITCH WITH ALL THE ROUTES
      <Switch>
        <Route exact path={ROUTES.HOME} component={Home}/>
        <Route exact path={ROUTES.ABOUT} component={About}/>
        <Route exact path={ROUTES.PRIVACY} component={Privacy}/>
        // ETC
      </Switch>
    </AllRoutes>
  </Main>
  <Footer/>         // <==== FOOTER NEEDS TO KNOW WHICH ROUTE HAS BEEN MATCH
<Router>

问题

页脚需要知道<Route/>匹配的内容。实现这一目标的最佳模式是什么?


选项1

我在反应路由器文档useRouteMatch上找到了钩子:

在此处输入图像描述

在此处输入图像描述

这会起作用,但我认为这对我的情况来说还不够好。因为一个 URL 字符串可以匹配一个路由,但同时仍然不是一个有效的路由。

例如:

一旦路由匹配,我通常需要在渲染组件页面或 404 页面之前检查它是否有效。

喜欢:

<Route exact path={"/:language/privacy"} render={(routeProps) => {
 const possibleLanguage = routeProps.match.params.language;
 if (possibleLanguage in LANGUAGES) {
   return(
     <PrivacyPage lang={possibleLanguage}/>
   );
 }
 else {
  return(
    <Page404/>
  );
 }
}}/>

选项#2

我正在考虑做的是:

像这样的东西:

沙盒链接

export default function App() {
  console.log("Rendering App...");

  const location = useLocation();

  // THIS WOULD BE THE detectRoute FUNCTION
  // I COULD EVEN USE THE useRouteMatch HOOK IN HERE
  const matchedRoute =
    location.pathname === ROUTE1
      ? "ROUTE1"
      : location.pathname === ROUTE2
      ? "ROUTE2"
      : "404";

  return (
    <div>
      <div className="App">
        <Link to={ROUTE1}>Route 1</Link>
        <Link to={ROUTE2}>Route 2</Link>
        <Link to={"/whatever"}>Route 404</Link>
      </div>
      <div>
        <AllRoutes matchedRoute={matchedRoute} />
      </div>
    </div>
  );
}

function AllRoutes(props) {
  switch (props.matchedRoute) {
    case "ROUTE1":
      return <Route exact path={ROUTE1} component={Page1} />;
    case "ROUTE2":
      return <Route exact path={ROUTE2} component={Page2} />;
    default:
      return <Route exact path={"*"} component={Page404} />;
  }
}

有用。但我想知道是否有合适的方法来做这件事,因为这看起来有点奇怪,而且可能有专门为此设计的东西。

标签: javascriptreactjsreact-routerreact-router-dom

解决方案


我最终做了什么:

因为我使用的是 Redux,所以我添加了一个全局状态来跟踪匹配的路由。

然后我调度操作以从's 组件的renderprop更新该状态。<Route/>

<Switch>
  <Route key={index} exact path={"/some-route"} render={(routeProps) => {

    // HERE I DISPATCH AN ACTION TO CHANGE THE STATE FOR THE CURRENT ROUTE

    dispatch({
      type: UPDATE_CURRENT_ROUTE,
      payload: { name: "SOME_ROUTE_NAME" }
    });

    return (
      <PrivacyPage
        {...routeProps}
      />
    );

  }}/>
</Switch>

现在我可以在Footer.js上做:

function Footer() {

  const currentRoute = useSelector((state) => state.currentRoute);

  // RENDER FOOTER ACCORDINGLY TO THE CURRENT ROUTE
}

推荐阅读