Search code examples
reactjsreact-router-dom

Dynamically populate react-router-dom's Route elements


I have a json file that contains the following information.

"id": "1",
"name": "Home",
"url": "/",
"component": "Home.js"

Using the information in the json file I want to populate the routing for my react webpage. I am trying to do this all dynamically. I am stuck on how to configure the element in the react-rounter-dom.

I thought that I could lazy to import the webpages and set the element to that but I think that because element requires a react component not an imported file it doesnt work.

Here are the relevant parts of my code.

Lazy loading the webpages

const [pages, setPages] = useState([]);
useEffect(() => {
    const addPage = () => {
      const newPage = [];
      for (let i = 0; i < 5; i++) {
        newPage.push(lazy(() => import(`./pages/${menuItems.pages[i].component}`)));
      }
      setPages(newPage);
    };  

    addPage();

  }, [menuItems])

The Route code

menuItems.pages.map((menuItem, index) => (
            <Routes>              
                <Route
                  key={index}                
                  path={menuItem.url}
                  component={pages[index]}
                />              
            </Routes>
          ))

Is what I want to do possible?


Solution

  • I solved this, I was being a bit silly. The crux of the issue was not checking to ensure that the pages variable had been populated. I also found that I should set page rather than trying to set pages[index] in elements.

    <Suspense fallback={<p>Loading...</p>}>
            {menuItems.pages && menuItems.pages.length > 0 && <Navbar menuItems={menuItems} />}
            <Routes>
              {menuItems.pages && menuItems.pages.length > 0 && pages && pages.length > 0 &&
                menuItems.pages.map((menuItem, index) => {
                  const Page = pages[index];
                  return (
                    <Route
                      key={menuItem.id}
                      path={menuItem.url}
                      element={<Page />} 
                    />
                );
              })}
            </Routes>
          </Suspense>