【发布时间】:2020-08-20 06:04:54
【问题描述】:
我在我的 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
我在react router docs 上找到了useRouteMatch 挂钩:
这有点用,但我认为这对我的情况来说还不够好。因为一个 URL 字符串可以匹配一个路由,但同时仍然不是一个有效的路由。
例如:
- 路线:
/:language/privacy - 有效路线:
/en/privacy - 无效的路由也将匹配:
/notALanguage/privacy
一旦一个路由匹配了,我通常需要在渲染组件页面或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
我正在考虑做的是:
-
App.js致电useLocation。因此,当路线发生变化时,它总是会重新渲染。 - 我可以在
App.js中添加一个detectRoute函数来预先进行所有路线检查。 - 我的
AllRoutes组件不需要组件。我会实现一个原生 JS 开关并渲染相应的路由。 - 这样我就可以预先知道哪个
<Route/>将匹配,我可以将它传递给<Footer/>或匹配的<Route/>之外的任何组件。
类似这样的:
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} />;
}
}
它有效。但我想知道是否有适当的方法来做这件事,因为这看起来有点奇怪,而且可能有专门为此设计的东西。
【问题讨论】:
标签: javascript reactjs react-router react-router-dom