【问题标题】:Using Reach Router with nested routes fails to parse params使用带有嵌套路由的到达路由器无法解析参数
【发布时间】:2020-07-16 13:08:35
【问题描述】:

使用 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)

当我转到 /g/123 时,它会呈现 PostsView,它工作正常,并且我在 GroupPage 内收到 123 的 groupId,但是当我转到 /g/123/about 时,groupId 丢失并且params 为空(仍然在 GroupPage 内使用 useParams 时)。

如果我将useParamsGroupPage 移动到嵌套的AboutView,那么我可以从/g/123/about 接收paramsgroupId,但这很令人沮丧,因为我不想拥有重复多个嵌套组件的逻辑,宁愿将其放在外部 GroupPage 组件中(这需要 groupId 来查询 API 以获取组相关数据,然后我使用上下文使其可用于这些嵌套组件) .

我做错了什么,有没有办法实现我的需要?谢谢。

【问题讨论】:

    标签: reactjs reach-router


    【解决方案1】:

    我发现我可以使用带有通配符的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

    这总是返回 PostsView 和 AboutView 路由的 groupId。

    除非有人知道更好的方法,否则我们可以考虑解决这个问题:)

    【讨论】:

      【解决方案2】:

      您将不会获得 AboutView 组件的 useParams() 的任何参数,因为该路由没有任何参数。

      您可以在上下文中设置 groupId 并在 AboutView 中使用它

      【讨论】:

      • 当我将 useParams() 移动到 AboutView 中时,它确实可以工作。您所描述的“您可以在上下文中设置 groupId 并在 AboutView 中使用它”是我想要通过获取 GroupPage 外部组件内部的 groupId 来做的,但这不起作用。
      • 我尝试改写它以使其更清晰。我希望这更有意义。
      【解决方案3】:

      也许这个解决方案会对你有所帮助:

      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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-23
        • 1970-01-01
        • 2015-08-19
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多