Ahmed Ali
Ahmed Ali

Reputation: 17

React router doesn't reload components on change

When route change from project to home the menu component still on. I just want it to destroy with changing of the routes and remount on the top of next route.

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import { Provider } from "react-redux";
import {
  createBrowserRouter,
  createRoutesFromElements,
  Route,
  RouterProvider,
} from "react-router-dom";
import App from "./App";
import Home from "./Routes/Home";
import Project from "./Routes/ProjectRoute";
import Store from "./Store";

const root = ReactDOM.createRoot(document.getElementById("root"));
const router = createBrowserRouter(
  createRoutesFromElements(
    <Route path="/" element={<App />}>
      <Route element={<Home />} index />
      <Route path="/:project" element={<Project />} />
    </Route>
  )
);

root.render(
  <Provider store={Store}>
    <RouterProvider router={router} />
  </Provider>
);

App.js

import { Box } from "@mui/material";
import { useSelector } from "react-redux";
import { Outlet } from "react-router-dom";
import TopScroll from "./Components/TopScroll";
import "./Style/app.scss";
import { menu } from "./NavSlice";
import { useEffect } from "react";
import Header from "./Components/Header";
import Menu from "./Components/Menu";

function App() {
  const menuOpened = useSelector(menu);

  useEffect(() => {
    menuOpened
      ? document.body.classList.add("stop-scrolling")
      : document.body.classList.remove("stop-scrolling");
  }, [menuOpened]);

  return (
    <Box position={"relative"} overflow="hidden">
      <TopScroll />
      <Header />
      {menuOpened && <Menu />}
      <Outlet />
    </Box>
  );
}

export default App;

useNavigate to move to next route functionally

onClick={() => {
  if (pathname === "/") {
    return null;
  }
  navigate("/", { replace: true });
}}

I tried NavLink but still the same issue

I tried to remove the Menu component from App.js and rendering it inside each of home and project mainRoutes but it still the same.

Upvotes: 1

Views: 434

Answers (1)

Drew Reese
Drew Reese

Reputation: 202846

If I'm understanding the post correctly it seems you want to close the menu when navigating from one route to another.

It looks like the menu is "controlled" by some Redux state.

function App() {
  const menuOpened = useSelector(menu); // <-- controlled by Redux state

  useEffect(() => {
    menuOpened
      ? document.body.classList.add("stop-scrolling")
      : document.body.classList.remove("stop-scrolling");
  }, [menuOpened]);

  return (
    <Box position={"relative"} overflow="hidden">
      <TopScroll />
      <Header />
      {menuOpened && <Menu />}
      <Outlet />
    </Box>
  );
}

What I'd suggest then is to dispatch the "closeMenu" action when a menu item is selected and the app is navigating to another route.

Menu

import { useDispatch } from 'react-redux';
import { closeMenu } from '../../NavSlice'; // <-- check path
...

const dispatch = useDispatch();

...

onClick={() => {
  dispatch(closeMenu()); // <-- close menu then handle navigation

  if (pathname === "/") {
    return null;
  }

  navigate("/", { replace: true });
}}

Upvotes: 2

Related Questions