# shouldComponentUpdate

## `shouldComponentUpdate()`

`shouldComponentUpdate()` allows us to determine if a component should update or not. It is used to avoid unnecessary tree re-rendering. It works in following way:

* It receives upcoming props and state and compares them to current props and state.&#x20;
* The component **should update** if `true` is returned, and **should not update** if `false` is returned.

{% tabs %}
{% tab title="GrandChild.js" %}

```jsx
import React, {Component} from "react"

class GrandChild extends Component {
    render() {
        console.log("[ ]   [ ]   [ ]   [👶🏻] rendered")
        return (
            <div>
                <p>I'm a GrandChild Component</p>
            </div>
        )
    }
}

export default GrandChild
```

{% endtab %}

{% tab title="Child.js" %}

```jsx
import React, {Component} from "react"
import GrandChild from "./GrandChild"

class Child extends Component {
    render() {
        console.log("[ ]   [ ]   [🧒🏻]   [ ] rendered")
        return (
            <div>
                <p>I'm a Child Component</p>
                <GrandChild />
                <GrandChild />
            </div>
        )
    }
}

export default Child
```

{% endtab %}

{% tab title="Parent.js" %}

```jsx
import React, {Component} from "react"
import Child from "./Child"

class Parent extends Component {
    render() {
        console.log("[ ]   [👩🏼‍⚕️]   [ ]   [ ] rendered")
        return (
            <div>
                <p>I'm a Parent Component</p>
                <Child />
                <Child />
            </div>
        )
    }
}

export default Parent
```

{% endtab %}

{% tab title="GrandParent.js" %}

```jsx
import React, {Component} from "react"
import Parent from "./Parent"

class GrandParent extends Component {

    // shouldComponentUpdate lifecycle method 
    shouldComponentUpdate(nextProps, nextState){
    
    // Here after changing the state since the 'upcoming state' is not equal to 'current state' it will return true hence re-render the whole DOM Tree
        if (nextProps.count === this.props.count){
            return false // Component Shouldn't update
        }
        return true // Component Should update
    } 
       
    render() {
        console.log("[👴🏼]   [ ]   [ ]   [ ] rendered")
        return (
            <div>
                <p>I'm a GrandParent Component</p>
                <Parent />
                <Parent />
            </div>
        )
    }
}

export default GrandParent
```

{% endtab %}

{% tab title="App.js" %}

```jsx
import React, {Component} from "react"
import GrandParent from "./GrandParent"

class App extends Component {
    state = { count: 0 }
    
    increment = () => this.setState(prevState => ({count: prevState.count + 1}))
    
    render() {
        console.log("[GP] [P] [C] [GC] APP just rendered")
        return (
            <div>
                <button onClick={this.increment}>+1</button>
                <h2>{this.state.count}</h2>
                <p>I'm the App component</p>
                
                // Passing 'count' props
                <GrandParent count={this.state.count} />
                <GrandParent count={this.state.count} />
            </div>
        )    
    }
}

export default App
```

{% endtab %}

{% tab title="index.js" %}

```jsx
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))
```

{% endtab %}
{% endtabs %}

This is the result of above operation:

```javascript
// Initial Tree rendering
[GP] [P] [C] [GC] APP just rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered

// Tree re-rendering after state change (Whole tree is re-rendered)
[GP] [P] [C] [GC] APP just rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
```

{% hint style="info" %}
&#x20;We see the entire tree re-rendered. Here, we are passing the **props** to **Grandparent component.**&#x20;

After changing the state `shouldComponentUpdate()` determines that the **upcoming state** is **NOT EQUAL** to **current state.**&#x20;

Hence, it returns `true` and re-render the whole DOM Tree.
{% endhint %}

Now if we omit the **prop** that's passed to Grandparent component we see the tree isn't re-rendering anymore. Here is the result after **omitting props** from Grandparent component.

```javascript
// Initial Tree rendering
[GP] [P] [C] [GC] APP just rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[👴🏼] [ ] [ ] [ ] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [👩🏼‍⚕️] [ ] [ ] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [🧒🏻] [ ] rendered
[ ] [ ] [ ] [👶🏻] rendered
[ ] [ ] [ ] [👶🏻] rendered

// Tree re-rendering after state change (Only the App component is re-rendered)
[GP] [P] [C] [GC] APP just rendered
```

{% hint style="info" %}
We see only App component re-rendered.&#x20;

Since we omitted prop from Grandparent componen&#x74;**,** after changing the state `shouldComponentUpdate()` determines that the **upcoming state** & **current state** both are `null` which makes them **EQUAL .**&#x20;

Hence, it returns `false` and **DON'T** re-render the whole DOM Tree anymore.
{% endhint %}
