How to do nested routing with api response

Viewed 87

In our current project, my leads want to control everything from admin panel. They want to add/change content of layouts from panel and i have to send request to get layout info to change ui accordingly. And also routes will change dynamically with this response.

I have an api response similar to the following below. I need to get react components with "component" and routes with "url" by using it.

[
  {
    "__typename": "Layout",
    "order": 2,
    "title": "{\"en\":\"our services\",\"tr\":\"servislerimiz\"}",
    "is_hidden_from_footer": false,
    "is_hidden_from_header": false,
    "meta_data": null,
    "private_meta_data": null,
    "seo_meta_data": null,
    "category_path": "-",
    "parent_uuid": "-",
    "url": "/our-services",
    "component": "OurServices",
    "children": [
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"digital transformation\",\"tr\":\"dijital dönüşüm\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "digital-transformation",
        "component": "DigitalTransformation"
      },
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"Managed IT Services\",\"tr\":\"managed it services\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "managed-it-services",
        "component": "ManagedItServices"
      },
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"sap consulting\",\"tr\":\"sap consulting\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "sap-consulting",
        "component": "SapConsulting"
      },
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"Devops\",\"tr\":\"Devops\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "devops",
        "component": "Devops"
      },
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"application managemenet\",\"tr\":\"application management tr\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "application-management",
        "component": "ApplicationManagement"
      },
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"QA\",\"tr\":\"QA tr\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "qa-testing-services",
        "component": "QATestingServices"
      }
    ]
  },
  {
    "__typename": "Layout",
    "order": 3,
    "title": "{\"en\":\"insight\",\"tr\":\"insight tr\"}",
    "is_hidden_from_footer": false,
    "is_hidden_from_header": false,
    "meta_data": null,
    "private_meta_data": null,
    "seo_meta_data": null,
    "category_path": "-",
    "parent_uuid": "-",
    "url": "/insight",
    "component": "Insight",
    "children": [
      {
        "__typename": "Layout",
        "order": 3,
        "title": "{\"en\":\"digital transformation\",\"tr\":\"dijital dönüşüm\"}",
        "is_hidden_from_footer": false,
        "is_hidden_from_header": false,
        "meta_data": null,
        "private_meta_data": null,
        "seo_meta_data": null,
        "category_path": "-",
        "parent_uuid": "-",
        "url": "digital-transformation",
        "component": "DigitalTransformation"
      }
    ]
  }
]

I write this render method but there are warnings.

export const RenderRoutes = ({ routes = [] }) => {
  return (
    <Suspense fallback={<div>loading</div>}>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Layout headerData={routes} />}>
            {routes.length &&
              routes.map((item, index) => {
                let Comp = lazy(() => import(`../pages/${item.component}`));

                return (
                  <Route
                    key={index}
                    path={item.url}
                    render={() => {
                      return <Comp />;
                    }}
                  >
                    {item.children.map((child, i) => {
                      let ChildComponent = lazy(() =>
                        import(`../pages/${item.component}/${child.component}`)
                      );

                      return (
                        <Route
                          key={index}
                          path={child.url}
                          render={() => {
                            return <ChildComponent />;
                          }}
                        />
                      );
                    })}
                  </Route>
                );
              })}
          </Route>
        </Routes>
      </BrowserRouter>
    </Suspense>
  );
};

enter image description here

So how can I handle this? Thank you for your help.

1 Answers

I think you've a few issues:

  1. In react-router-dom v6 the Route components no longer have a component prop or render and children prop functions. They were replaced by a single element prop taking a ReactElement, a.k.a. JSX.
  2. The nested inner (children) routes are incorrectly using the parent route's index as their React keys. Don't use the mapped index, instead use the url property as this needs to be unique among sibling routes anyway.
  3. Remove the BrowserRouter and render only a single router higher in the ReactTree so any links in the app elsewhere can work correctly.

Code:

export const RenderRoutes = ({ routes = [] }) => {
  return (
    <Suspense fallback={<div>loading</div>}>
      <Routes>
        <Route path="/" element={<Layout headerData={routes} />}>
          {routes.map((item) => {
            let Comp = lazy(() => import(`../pages/${item.component}`));

            return (
              <Route key={item.url} path={item.url} element={<Comp />}>
                {item.children.map((child) => {
                  let ChildComponent = lazy(() =>
                    import(`../pages/${item.component}/${child.component}`)
                  );

                  return (
                    <Route
                      key={child.url}
                      path={child.url}
                      element={<ChildComponent />}
                    />
                  );
                })}
              </Route>
            );
          })}
        </Route>
      </Routes>
    </Suspense>
  );
};
Related