将Reach Router与嵌套路由一起使用无法解析参数

时间:2020-07-16 13:08:35

标签: reactjs reach-router

使用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的{​​{1}}时,它工作正常,并且在PostsView中收到123中的groupId,但是当我转到{{ 1}} GroupPage丢失并且/g/123/about为空(在groupId内使用params时仍然如此)。

如果将useParamsGroupPage移到嵌套的useParams,那么我可以从GroupPage接收AboutViewparams但这令人沮丧,因为我不想重复多个嵌套组件的逻辑,而是希望将其放在外部groupId组件中(该组件需要/g/123/about来查询与组相关的API数据,然后使用上下文将其用于那些嵌套的组件。

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

3 个答案:

答案 0 :(得分:2)

我发现可以将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。

除非有人知道更好的方法,否则我们可以认为此问题已解决:)

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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;