Search code examples
javascriptreactjsmaterial-uireact-routerreact-router-dom

React Router Wrapped in a BottomNavigation not loading the new component


I can not for the life of me figure out how to load the DMO page from a BottomNavigation component. Going to "/dom" works perfectly. Clicking the buttons does not work at all. The initial "/" loads great. Thoughts? Suggestions?

import * as React from 'react';
import Box from '@mui/material/Box';
import BottomNavigation from '@mui/material/BottomNavigation';
import BottomNavigationAction from '@mui/material/BottomNavigationAction';
import AccountTreeIcon from '@mui/icons-material/AccountTree';
import DatasetLinkedIcon from '@mui/icons-material/DatasetLinked';
import LogoutIcon from '@mui/icons-material/Logout';
import './navigation.css'
import {createBrowserRouter, Link, RouterProvider} from 'react-router-dom';
import PmoTable from "../PmoTable/PmoTable";
import DMO from "../DMO/DMO";

export default function Navigation() {
  const [value, setValue] = React.useState(0);
  const router = createBrowserRouter([
    {
      path: "/",
      element: <PmoTable />,
    },
    {
      path: "dmo",
      element: <DMO />,
    }
  ]);

  return (
    <Box className="navBar">
      <RouterProvider router={router} />
      <BottomNavigation
        showLabels
        value={value}
        onChange={(event, newValue) => {
          setValue(newValue);
        }}
      >
        <BottomNavigationAction label="PMO" icon={<AccountTreeIcon />} >
          <Link to='/'></Link>
        </BottomNavigationAction>
        <BottomNavigationAction label="DMO" icon={<DatasetLinkedIcon />} >
          <Link to='/dmo'></Link>
        </BottomNavigationAction>
        <BottomNavigationAction label="Logout" icon={<LogoutIcon />} >
          <Link to='/logout'></Link>
        </BottomNavigationAction>
      </BottomNavigation>
    </Box>
  );
}

Solution

  • The BottomNavigation, or more specifically the Link components it renders, needs to be rendered within the routing context provided by the BrowserRouter. Move the BottomNavigation into a layout route component so it can be rendered within the router.

    The the Link components are also empty which means they have to clickable/interactable area. Rewrite the code to render the BottomNavigationAction as Link components and pass the link props through.

    Example:

    import {
      createBrowserRouter,
      Link,
      RouterProvider,
      Outlet,
    } from 'react-router-dom';
    
    export default function Navigation() {
      const [value, setValue] = React.useState(0);
    
      const router = createBrowserRouter([
        {
          element: (
            <>
              <Outlet />
              <BottomNavigation
                showLabels
                value={value}
                onChange={(event, newValue) => {
                  setValue(newValue);
                }}
              >
                <BottomNavigationAction
                  component={Link}
                  label="PMO"
                  icon={<AccountTreeIcon />}
                  to='/'
                />
                <BottomNavigationAction
                  component={Link}
                  label="DMO"
                  icon={<DatasetLinkedIcon />}
                  to='/dmo'
                />
                <BottomNavigationAction
                  component={Link}
                  label="Logout"
                  icon={<LogoutIcon />}
                  to="/logout"
                />
              </BottomNavigation>
            </>
          ),
          children: [
            {
              path: "/",
              element: <PmoTable />,
            },
            {
              path: "dmo",
              element: <DMO />,
            }
          ],
        },
      ]);
    
      return (
        <Box className="navBar">
          <RouterProvider router={router} />
        </Box>
      );
    }