1

Open the sidebar example in official docs of react router. You can see that ul is rendered without Route since it is supposed to be there on screen irrespective of the url. Open React DevTools, check Highlight updates checkbox and click on any of the menu items in the side bar. You will notice that elements under ul re-render on every click. In my opinion, it is not sane behavior, react elements under ul should not re-render with route change given they are not rendered by react routers Route component. Is there a way I can stop them re-rendering?

Muhammad Saqib
  • 795
  • 2
  • 8
  • 13

1 Answers1

2

A Router component depends on context for the change and whenver a context value is updated, it triggers a re-render of the children to do a match and render the appropriate route. Now since the ul element is directly written as a child of Router, it also gets re-rendered. Although react performs a virtual-dom comparison and the DOM won't be re-rendered, you can avoid it by using a PureComponent and writing ul elements within that Component

const SidebarExample = () => (
  <Router>
    <div style={{ display: "flex" }}>
      <div
        style={{
          padding: "10px",
          width: "40%",
          background: "#f0f0f0"
        }}
      >
        <Route component={Elements}/>
        {routes.map((route, index) => (
          // You can render a <Route> in as many places
          // as you want in your app. It will render along
          // with any other <Route>s that also match the URL.
          // So, a sidebar or breadcrumbs or anything else
          // that requires you to render multiple things
          // in multiple places at the same URL is nothing
          // more than multiple <Route>s.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.sidebar}
          />
        ))}
      </div>

      <div style={{ flex: 1, padding: "10px" }}>
        {routes.map((route, index) => (
          // Render more <Route>s with the same paths as
          // above, but different components this time.
          <Route
            key={index}
            path={route.path}
            exact={route.exact}
            component={route.main}
          />
        ))}
      </div>
    </div>
  </Router>

)

class Elements extends React.PureComponent {
    render() {
        return (
          <ul style={{ listStyleType: "none", padding: 0 }}>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/bubblegum">Bubblegum</Link>
            </li>
            <li>
              <Link to="/shoelaces">Shoelaces</Link>
            </li>
          </ul>
        )
    }
}
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318