Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the whole DOM re-render when navigating between routes?

I am learning react so forgive me if this has been asked a million times but I have browsed and no solution has fixed my issue. Apart from fixing the issue I would like to understand how the mechanics under the hood work...

I have 2 simple components NavBar and Home. Code below for both.

NavBar:

import React from "react";

class NavBar extends React.Component {
    render () {

        return (

            <nav className="navbar sticky-top navbar-light" style={NavBarStyle}>
                <a className="navbar-brand" href="/">
                    <img src={require('./av_tiny.png')} style={ImageStyle} alt="Logo"></img>
                </a>
            </nav>
        )
    }

}

const NavBarStyle = {
    // some styling
}

const ImageStyle = {
    width: '100px',
    height: '50px',
    marginLeft: '20px'
}

export default NavBar;

Home:

import React from "react";

class Home extends React.Component {
    render(){

        return(
            <h1>Home</h1>
        );
    }
}

export default Home;

When I navigate between routes, the whole DOM re-renders. I don't want the NavBar to re-render. My routes are declared in App.js as per below, and I have tried moving <NavBar /> outside the <Router> tags and the other way around. I have also tried putting <NavBar /> in its own <div> tags. Still the app behaves the same, whenever I change the URL it re-renders everything. How can this be avoided and what should I read up to properly understand the mechanics?

import React from 'react';
import {BrowserRouter as Router, Route} from "react-router-dom";

//individual components
import Home from "./Home";
import SignInPage from "./Components/Login";
import NavBar from "./Components/Layout/NavBar"

//Routing to components
class App extends React.Component {
  render() {

    return(
          <div>
            <NavBar/>
            <Router>
                    <Route exact path="/" component={Home}/>
                    <Route exact path="/login" component={SignInPage}/>      
            </Router>
          </div>
    )
  }
}

export default App;

EDIT:

I think I should've mentioned that re-renders happen when I navigate by manually changing the URL in the browser. I have some code on my /login route that does this.props.history.push('/'); after successful login and the DOM does not re-render. Just {SignInPage} gets unmounted and {Home} gets mounted. I would expect the same behavior when navigating between the pages manually or am I missing something?

like image 815
asleniovas Avatar asked Oct 22 '25 09:10

asleniovas


1 Answers

The reason why it re-renders hole dom is that the router is changing root properties.

Take a look at nested routers, it will give you an idea of how to achieve your goal Nested routes with react router v4 / v5

like image 51
OttoV Avatar answered Oct 25 '25 00:10

OttoV