Skip to content

Unnecessary reflow due to setState in componentWillReceiveProps #1940

@univerio

Description

@univerio

See mailing list post, reproduced below for convenience:

The following reduced test case (jsfiddle) has an unnecessary reflow:

var Input = React.createClass({
    getInitialState: function () {
        return {
            text: this.props.text + "..."
        };
    },
    componentWillReceiveProps: function (nextProps) {
        this.setState({
            text: nextProps.text + "..."
        });
    },
    render: function () {
        return React.DOM.div(null, this.state.text);
    }
});

var App = React.createClass({
    getInitialState: function () {
        return {
            value: "foo"
        };
    },
    render: function () {
        var that = this;
        return React.DOM.div(null,
            React.DOM.input({
                value: this.state.value,
                onChange: function (e) {
                    that.setState({
                        value: e.target.value
                    });
                }
            }),
            Input({
                text: this.state.value
            }));
    }
});

React.renderComponent(App(null), document.body);

And a screenshot from the Timeline tab in Chrome Dev Tools showing the reflow:

reflow

An equivalent implementation (jsfiddle) not using setState in componentWillReceiveProps does not have the same reflow:

var Input = React.createClass({
    render: function () {
        return React.DOM.div(null, this.props.text + "...");
    }
});

var App = React.createClass({
    getInitialState: function () {
        return {
            value: "foo"
        };
    },
    render: function () {
        var that = this;
        return React.DOM.div(null,
            React.DOM.input({
                value: this.state.value,
                onChange: function (e) {
                    that.setState({
                        value: e.target.value
                    });
                }
            }),
            Input({
                text: this.state.value
            }));
    }
});

React.renderComponent(App(null), document.body);

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions