If the props for a child component are unchanged, does React still re-render it?

10,286

When React re-renders ParentComponent it will automatically re-render ChildComponent. The only way to get around is to implement shouldComponentUpdate in the ChildComponent. You should compare this.props.a, this.props.b and this.props.c and ChildComponents own state to decide to re-render or not. If you are using immutable data than you can just compare previous and next state and props using strict equality ===.

There are a few thing to note with your code

  1. You dont need to forceUpdate when you setState. React automatically does it for you.
  2. You probably meant:

    <ChildComponent a={this.props.a} b={this.props.b} c={this.props.c}/>

Share:
10,286

Related videos on Youtube

AlexZ
Author by

AlexZ

Updated on September 16, 2022

Comments

  • AlexZ
    AlexZ over 1 year

    Suppose I have the following pairing of parent and child components in React:

    var ChildComponent = React.createClass({
        getDefaultProps: function(){
            return {
                a: 'a',
                b: 'b',
                c: 'c'
            }
        },
    
        render: function() {
            return (
                /* jshint ignore:start */
                <div className={'child' + (this.props.b ? ' modifierClass' : '')} something={this.props.a}>
                    {this.props.c}
                </div>
                /* jshint ignore:end */
            );
        }
    });
    
    
    var ParentComponent = React.createClass({
        componentDidMount: function(){
            //After 10 seconds, change a property that DOES NOT affect the child component, and force an update
            setTimeout(function(){
                this.setState({foo: 'quux'});
                this.forceUpdate();
            }.bind(this), 10000);
        }
    
        getInitialState: function(){
            return {
                foo: 'bar',
                a: 1,
                b: 2,
                c: 3
            }
        },
    
        render: function() {
            return (
                /* jshint ignore:start */
                <div className="parent">
                    <ChildComponent a={this.props.a} b={this.props.b} c={this.props.c}/>
                </div>
                /* jshint ignore:end */
            );
        }
    });
    
    
    React.render(
        /* jshint ignore:start */
        <ParentComponent />, 
        /* jshint ignore:end */
        document.getElementsByTagName('body')[0]
    );
    

    When I do the forceUpdate, since none of the props that were passed to the ChildComponent changed, will React try to re-render it? What if I have 1000 such children, etc?

    What I'm worried about is a situation where I have a very deep ChildComponent containing a whole massive tree of descendant components, but I only want to enact some relatively cosmetic changes on the ParentComponent. Is there any way to get React to update only the parent, without trying to re-render the children as well?

  • AlexZ
    AlexZ about 9 years
    Wow, that's exactly what I was looking for! Follow up question - is there any way to update the parent component while still allowing shouldComponentUpdate to execute on the children? Currently, when my Backbone model emits a change event, my ParentComponent executes a forceUpdate. Is there anything I can do to "force" an update, but still invoke shouldComponentUpdate on the children?
  • AlexZ
    AlexZ about 9 years
    React docs beg to differ. When using forceUpdate, it says that shouldComponentUpdate is ignored.
  • nilgun
    nilgun about 9 years
    shouldComponentUpdate is called automatically on the ChildComponent, you dont have to do anything about it. forceUpdate skips the shouldComponentUpdate method of ParentComponent.
  • nilgun
    nilgun about 9 years
    here is a jsfiddle: jsfiddle.net/p7v59d0r. You can look at the logs on the console.
  • AlexZ
    AlexZ about 9 years
    Ah, gotcha! Thanks for the fiddle too!