将 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 时仍然如此)。

如果我将 useParamsGroupPage 移动到嵌套的 AboutView,那么我可以从 [=13] 接收 paramsgroupId =] 但这令人沮丧,因为我不想重复多个嵌套组件的逻辑,而宁愿将它放在外部 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;