javascript - 如何检测来自外部组件的匹配路由使用 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 字符串可以匹配一个路由,但同时仍然不是一个有效的路由。
例如:
- 路线:
/: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
。因此,当路线发生变化时,它总是会重新渲染。- 我可以添加一个
detectRoute
函数App.js
来预先进行所有路线检查。 - 而且我
AllRoutes
的组件不需要组件。我会实现一个原生 JS 开关并渲染相应的路由。 - 这样我就可以预先知道哪个
<Route/>
是匹配的,然后我可以将它传递给 match<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} />;
}
}
有用。但我想知道是否有合适的方法来做这件事,因为这看起来有点奇怪,而且可能有专门为此设计的东西。
解决方案
我最终做了什么:
因为我使用的是 Redux,所以我添加了一个全局状态来跟踪匹配的路由。
然后我调度操作以从's 组件的render
prop更新该状态。<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
}
推荐阅读
- gurobi - 我可以使用 Gurobi 获得特定约束的对偶值吗?
- sql - 如何在 Postgres 中指定的时间内查看每小时结果
- html - 在哪里可以找到默认显示的文档?
- javascript - javascript将对象/数组之类的字符串拆分为节点
- informatica-powercenter - 与 Informatica wokflow 监视器中的集成服务通信问题
- c# - 如何使用包含的源生成器发布 .Net 库?
- r - 如何为包括管道的代码创建循环
- node.js - nodejs中的简单http服务器:响应时间1毫秒很多吗?
- python - 计算 POS 标记模式的出现次数
- java - 将枚举映射到Java中代码量较少的另一个枚举