reactjsreact-routerreact-lazy-load

React Router mounting and unmounting parent component


I am creating a react app with react-router@latest and with code splitting. Everything works fine except the layout component re-renders everything when ever I click on About link or a dashboard link. Please help me out how to fix this. I had already read many blog posts but didn't get any solution that works for me.

I had created a repository for that https://github.com/riyasat/ReactRouterTest.

Here are my components

Main Component

const Main = () => {
  // const Layout = React.lazy(()=>import('../Core/Layout'));
    return (
        <div>
      <ErrorBoundary>
            Router Test
            <Switch>
                    <Route exact path="/">
                        <Redirect to="en"></Redirect>
                    </Route>
                    <Route path="/:lang"
                    >
            <Layout/>
          </Route>

            </Switch>
      </ErrorBoundary>
        </div>
    );
};
export default Main;

Layout Component

import React, { Suspense, useEffect } from "react";
import { Redirect, Route, Switch, useRouteMatch } from "react-router-dom";

const Layout = () => {
    const { url, path } = useRouteMatch();
    const About =React.lazy(() => import("../Views/About"));
    const Dashboard = React.lazy(() => import("../Views/Dashboard"));

    useEffect(() => {
        console.log("Layout Mounted");
        return () => {
            console.log("Un Mounted");
        };
    });
    return (
        <div>
            This is Router
            <Switch>
                <Route exact path={`${path}`}>
                    <Redirect to={`${url}/about`} />
                </Route>
                <Route exact path={`${path}/about`}>
          <About/>
        </Route>
                <Route exact path={`${path}/dashboard`} >
          <Dashboard/>
        </Route>
            </Switch>
        </div>
    );
};
export default Layout;

About Component

const About = () => {

  return (
    <div>
      <Link to="dashboard">Dashboard</Link>   
    </div>
  )
}
export default About;

Dashboard Component

const Dashboard = () => {
 
  return (
    <div>
      <NavLink to={`about`}>About</NavLink> 
    </div>
  )
}
export default Dashboard;

Solution

  • It's because the useRouteMatch causes the component it is in to re-render whenever there is a change in URL. If you remove that and change the url and path to a fixed value (i.e a string) then the Layout Component should not re-render when route change anymore