将 Reach Router 与嵌套路由一起使用无法解析参数
Using Reach Router with nested routes fails to parse params
使用 Reach 路由器(不是 React 路由器!)我有 2 个嵌套路由:
/g/123
/g/123/about
其中 123 是一个 :groupId
参数:
import React from "react";
import { Router } from "@reach/router";
import GroupPage from "../components/dynamic-pages/group";
import PostsView from "../components/group/views/posts";
import AboutView from "../components/group/views/about";
const App = () => {
return (
<Router>
<GroupPage path="/g/:groupId">
<PostsView path="/" />
<AboutView path="/about" />
</GroupPage>
</Router>
);
};
export default App;
并且在外部 GroupPage
组件中我需要使用 :groupId
参数:
const GroupPage: React.FC<RouteComponentProps> = ({ children }) => {
debugger;
const params = useParams();
const groupId = params.groupId as string;
// query an API using groupId and store it in a context to be
// accessible to other nested components (such as AboutView and PostsView)
当我转到呈现 PostsView
的 /g/123
时,它工作正常并且我在 GroupPage
中收到 123 的 groupId
,但是当我转到/g/123/about
groupId
丢失并且 params
为空(在 GroupPage
中使用 useParams
时仍然如此)。
如果我将 useParams
从 GroupPage
移动到嵌套的 AboutView
,那么我可以从 [=13] 接收 params
和 groupId
=] 但这令人沮丧,因为我不想重复多个嵌套组件的逻辑,而宁愿将它放在外部 GroupPage
组件中(需要 groupId
来查询 API 用于组相关数据,然后我使用上下文使其可用于那些嵌套组件)。
我做错了什么吗?有什么方法可以实现我的需要吗?谢谢。
您不会获得 AboutView 组件的 useParams() 的任何参数,因为该路由在那里没有任何参数。
您可以在上下文中设置groupId并在AboutView中使用它
我发现我可以使用带有通配符的 useMatch
来实现这一点:
const GroupPage: React.FC<RouteComponentProps> = ({ children }) => {
debugger;
const match = useMatch("/g/:groupId/*");
const groupId = match?.groupId as string;
文档:https://reach.tech/router/api/useMatch
这始终是 returns PostsView 和 AboutView 路由的 groupId。
除非有人知道更好的方法,否则我们可以认为这个问题已解决:)
也许这个解决方案可以帮助您:
import React from "react";
import { Router } from "@reach/router";
import GroupPage from "../components/dynamic-pages/group";
import PostsView from "../components/group/views/posts";
import AboutView from "../components/group/views/about";
const App = () => {
return (
<Router>
<GroupPage path="g/:groupId">
<PostsView path="/" />
</GroupPage>
<GroupPage path="g/:groupId/about">
<AboutView path="/" />
</GroupPage>
</Router>
);
};
export default App;
使用 Reach 路由器(不是 React 路由器!)我有 2 个嵌套路由:
/g/123
/g/123/about
其中 123 是一个 :groupId
参数:
import React from "react";
import { Router } from "@reach/router";
import GroupPage from "../components/dynamic-pages/group";
import PostsView from "../components/group/views/posts";
import AboutView from "../components/group/views/about";
const App = () => {
return (
<Router>
<GroupPage path="/g/:groupId">
<PostsView path="/" />
<AboutView path="/about" />
</GroupPage>
</Router>
);
};
export default App;
并且在外部 GroupPage
组件中我需要使用 :groupId
参数:
const GroupPage: React.FC<RouteComponentProps> = ({ children }) => {
debugger;
const params = useParams();
const groupId = params.groupId as string;
// query an API using groupId and store it in a context to be
// accessible to other nested components (such as AboutView and PostsView)
当我转到呈现 PostsView
的 /g/123
时,它工作正常并且我在 GroupPage
中收到 123 的 groupId
,但是当我转到/g/123/about
groupId
丢失并且 params
为空(在 GroupPage
中使用 useParams
时仍然如此)。
如果我将 useParams
从 GroupPage
移动到嵌套的 AboutView
,那么我可以从 [=13] 接收 params
和 groupId
=] 但这令人沮丧,因为我不想重复多个嵌套组件的逻辑,而宁愿将它放在外部 GroupPage
组件中(需要 groupId
来查询 API 用于组相关数据,然后我使用上下文使其可用于那些嵌套组件)。
我做错了什么吗?有什么方法可以实现我的需要吗?谢谢。
您不会获得 AboutView 组件的 useParams() 的任何参数,因为该路由在那里没有任何参数。
您可以在上下文中设置groupId并在AboutView中使用它
我发现我可以使用带有通配符的 useMatch
来实现这一点:
const GroupPage: React.FC<RouteComponentProps> = ({ children }) => {
debugger;
const match = useMatch("/g/:groupId/*");
const groupId = match?.groupId as string;
文档:https://reach.tech/router/api/useMatch
这始终是 returns PostsView 和 AboutView 路由的 groupId。
除非有人知道更好的方法,否则我们可以认为这个问题已解决:)
也许这个解决方案可以帮助您:
import React from "react";
import { Router } from "@reach/router";
import GroupPage from "../components/dynamic-pages/group";
import PostsView from "../components/group/views/posts";
import AboutView from "../components/group/views/about";
const App = () => {
return (
<Router>
<GroupPage path="g/:groupId">
<PostsView path="/" />
</GroupPage>
<GroupPage path="g/:groupId/about">
<AboutView path="/" />
</GroupPage>
</Router>
);
};
export default App;