2023 complete answer
Building on @thirdydot's answer and @trashgenerator's comment, filling in all the remaining gaps.
If you want to hook up BottomNavigation
with react-router-dom
then you want the router to hold the single point of truth. This means to rely on useLocation
instead of useState
to store this aspect of your app's state and Link
to change the state.
There's 3 steps to this:
- Make sure you are inside the router context for
useLocation
to work (see below).
- In
BottomNavigation
set value={useLocation().pathname}
instead of useState
and onChange
.
- In
BottomNavigationAction
use component={Link}
and to="/signal"
and set the value
to that same path.
src/components/RouterBottomNavigation.js
import { useLocation, Link } from 'react-router-dom';
import { BottomNavigation, BottomNavigationAction } from '@mui/material';
/* import icons */
export default function RouterBottomNavigation() {
return (
<BottomNavigation
value={useLocation().pathname}
className={classes.root}
>
<BottomNavigationAction
component={Link}
to="/signal"
value="/signal"
label="Signal"
icon={<ShowChart />}
className={classes.content}
/>
<BottomNavigationAction
component={Link}
to="/dashboard"
value="/dashboard"
label="Dashboard"
icon={<PermIdentity />}
className={classes.content}
/>
</BottomNavigation>
)
}
How does this work? The location pathname now holds the state for your bottom navigation.
If it's /dashboard
then your dashboard BottomNavigationAction
is active, because it's value is also /dashboard
.
And when you click a BottomNavigationAction
that is also a router Link
, you change the location pathname to the to
value.
On being inside the router comntext
And to be inside of the router context, you could place the RouterBottomNavigation
next to the Outlet
. For example:
src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Root from "./routes/root";
import Dashboard from "./routes/dashboard";
import Signal from "./routes/signal";
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
children: [
{
path: "dashboard",
element: <Dashboard />,
},
{
path: "signal",
element: <Signal />,
},
]
},
]);
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
src/routes/root.js
import { Outlet } from 'react-router-dom';
import RouterBottomNavigation from "../components/RouterBottomNavigation";
export default function Root() {
return (
<>
<Outlet />
<RouterBottomNavigation />
</>
);
}