英文:
Determine Which Route Was Resolved
问题
给定这样的路由:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:token" element={<Foo />} />
<Route path=":token" element={<Bar />}>
<Route path=":id" element={<Baz />} />
<Route>
</Route>
</Routes>
MainLayout
如何知道哪个路由已解析?我需要知道它是否在具有 path=":token"
的路由树内。
useMatch('/:token/*')
不起作用,因为它匹配到路径 foo/123
,这将解析为 path="foo/:token"
路由。
我弄不清楚 useResolvedPath
做什么或者我如何使用它。它似乎只是回显输入参数。
我不能使用 const { token } = useParams()
,因为这两个路由都有名为 token
的参数。
有什么想法吗?
英文:
Given routes like this:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:token" element={<Foo />} />
<Route path=":token" element={<Bar />}>
<Route path=":id" element={<Baz />}>
<Route>
</Route>
</Routes>
How can MainLayout
know which route was resolved? I need to know if it was within the route tree with path=":token"
.
useMatch('/:token/*')
does not work because it matches on path foo/123
, which resolves to the path="foo/:token"
route.
I can't figure out what useResolvedPath
does or how I could use it. I just seems to echo the input param.
I can't use const { token } = useParams()
since both routes have a param named token
.
Ideas?
答案1
得分: 1
看起来问题或者疑问实际上是关于如何区分两个定义了相同路径参数变量的路由。换句话说,您试图检查token
路径参数是从哪个路由填充而来。
我在这里的建议是使用不同的路径参数变量名称来消除歧义。
例如,使用fooToken
和barToken
:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:fooToken" element={<Foo />} />
<Route path=":barToken" element={<Bar />}>
<Route path=":id" element={<Baz />} />
<Route>
</Route>
</Routes>
MainLayout
组件可以检查这两者并有条件地应用逻辑。
const { barToken, fooToken } = useParams();
...
useEffect(() => {
if (barToken) {
// bar token 逻辑
}
if (fooToken) {
// foo token 逻辑
}
}, [barToken, fooToken]);
...
另一种方法是使用 useMatch
钩子,显式地检查每个具有 token
路径参数的路由是否匹配。
const MainLayout = () => {
const fooMatch = useMatch("/foo/:token"); // foo token
const barMatch = useMatch("/:token"); // bar token
const bazMatch = useMatch("/:token/:id"); // bar token
useEffect(() => {
console.log({ fooMatch, barMatch, bazMatch });
if (barMatch || bazMatch) {
// bar token 逻辑
}
if (fooMatch) {
// foo token 逻辑
}
}, [fooMatch, barMatch, bazMatch]);
return (
<>
...
<Outlet />
</>
);
};
英文:
It seems the issue, or question, is really about how to differentiate between the two routes that defined identical path parameter variables. In other words, you are trying to check which route the token
path param was populated from.
My suggestion here would be to use different path parameter variable names to disambiguate them.
For example fooToken
and barToken
:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:fooToken" element={<Foo />} />
<Route path=":barToken" element={<Bar />}>
<Route path=":id" element={<Baz />}>
<Route>
</Route>
</Routes>
The MainLayout
component can check for both and conditionally apply logic.
const { barToken, fooToken } = useParams();
...
useEffect(() => {
if (barToken) {
// bar token logic
}
if (fooToken) {
// foo token logic
}
}, [barToken, fooToken]);
...
An alternative would be to use the useMatch
hook and explicitly check for a match for each route that has a token
path parameter.
const MainLayout = () => {
const fooMatch = useMatch("/foo/:token"); // foo token
const barMatch = useMatch("/:token"); // bar token
const bazMatch = useMatch("/:token/:id"); // bar token
useEffect(() => {
console.log({ fooMatch, barMatch, bazMatch });
if (barMatch || bazMatch) {
// bar token logic
}
if (fooMatch) {
// foo token logic
}
}, [fooMatch, barMatch, bazMatch]);
return (
<>
...
<Outlet />
</>
);
};
答案2
得分: 0
我想错了,我的问题没有充分解释上下文。
MainLayout
包含全局导航元素,我希望针对不同的路由稍作调整。而不是让 MainLayout
朝外查看路由,路由设置应该告诉 MainLayout
要做什么。像这样:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:token" element={<Foo />} />
</Route>
<Route element={<MainLayout someParam={paramValue} />}>
<Route path=":token" element={<Bar />}>
<Route path=":id" element={<Baz />}>
<Route>
</Route>
</Routes>
MainLayout
使用 paramValue
以实现不同的行为。
英文:
I was thinking about this wrong, and my question did not explain the context well enough to spot it.
MainLayout
contains global nav elements that I want to be slightly different for different routes. Rather than have MainLayout
look outward at the route, the router setup should tell MainLayout
what to do. Like this:
<Routes>
<Route element={<MainLayout />}>
<Route path="foo/:token" element={<Foo />} />
</Route>
<Route element={<MainLayout someParam={paramValue} />}>
<Route path=":token" element={<Bar />}>
<Route path=":id" element={<Baz />}>
<Route>
</Route>
</Routes>
Where MainLayout
uses paramValue
to behave differently.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论