Ben Carp
Ben Carp

Reputation: 26568

React renders unnecessary components

In this simple Create-React-App application , I have a simple, static, Header component. For readability the header is held in a separate component. When using : Dveloper Tools - React - and selecting heighlight updates, I'm surprised to see that the Header component renders each time the destination changes. Of course this happens because the state of the parent, the App component, changes.

It was originally build as a functional component; I tried changing it to a React.pureComponent and React.Component with a 'shouldComponentUpdate' function that returns false but it did not help - the component still gets updated/rendered.

I guess this gets to the 'Virtual Dom' and does not render to the actual dom, but in more complicated apps it is still costly. Any suggestions? Code

Update

I've forked the original repository to demonstrate the issue. In this example the Header component is build with React.Component and shouldComponentUpdate returns false. Yet the header renders each time the destination changes. Code

Upvotes: 0

Views: 276

Answers (4)

Ben Carp
Ben Carp

Reputation: 26568

When returning false from the ShouldComponentUpdate method React does not run the render method. I confirmed it by adding a console.log command.

However Chrome’s React extension - heighlight updates - still heiglights the Header. The reason for it might be that Header is a sub-component of the App Component, and since the render method of App runs, the Header is heighlighted.

Upvotes: 1

Muhammad Danial Iqbal
Muhammad Danial Iqbal

Reputation: 1776

Currently Header is not a component that can implement shouldComponentUpdate.

Implement Header like this:

import React from 'react'
import '../App.css'
import globeLogo from './globe.svg'

export default class Header extends React.Component{

shouldComponentUpdate(nextProps, nextState) {
  //compare props and state if need to and decide whether to render or not
  //Other wise just return false;
}
render(){
 return (
        <div className="App-header">
            <img src={globeLogo} className="App-logo" alt="logo" />
          <h1>Choose My Next Destination</h1>
        </div>
    )
}
}

Hope that will resolve your query :)

Upvotes: 0

Audun Kvasb&#248;
Audun Kvasb&#248;

Reputation: 1

My suggestion is to not worry about it, just keep your render functions as cheap as possible and let React do its work.

If you take care to just pass inn the needed props to any component, keep the components as simple as possible and in a sane structure, and make any expensive calculations outside the simple components (to keep them between state changes), that's all the optimizing I would do.

Upvotes: 0

Shishir
Shishir

Reputation: 2546

The simplest solution I can think of is to convert your App component to a simple wrapper component around ControlPanel and presentation. Create a new App component which includes the Header and Footer, along with the wrapper component. Please ensure that the App does not have any state of it's own, to avoid re-renders.

Upvotes: 0

Related Questions