Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 558
AlexZ Avatar asked Feb 06 '15 08:02

AlexZ


1 Answers

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}/>

like image 181
nilgun Avatar answered Oct 12 '22 22:10

nilgun