Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unnecessary reflow due to setState in componentWillReceiveProps #1940

Closed
univerio opened this issue Jul 26, 2014 · 4 comments
Closed

Unnecessary reflow due to setState in componentWillReceiveProps #1940

univerio opened this issue Jul 26, 2014 · 4 comments

Comments

@univerio
Copy link

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);
@sophiebits
Copy link
Collaborator

See also #1439.

@theREALdebater
Copy link

In a React v16 component, I defined componentWillReceiveProps inside which I always called setState (on an object with several members, including other objects). This seems to have caused a runaway loop of re-renders, because when I added code to make the call to setState conditional the loop was no longer observed. I thought calling setState in componentWillReceiveProps (and also componentWillMount) was not meant to trigger a re-render. Am I wrong? Has this changed in v16?

@gaearon
Copy link
Collaborator

gaearon commented Oct 26, 2017

@theREALdebater This doesn't sound related to this issue, and no, setState in componentWillReceiveProps shouldn't trigger extra re-renders. Can you please file a new issue about this, with an example reproducing it?

@aweary
Copy link
Contributor

aweary commented Jun 25, 2018

I'm going to close this out since componentWillReceiveProps is scheduled to be deprecated and this doesn't appear to be a significant issue.

@aweary aweary closed this as completed Jun 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants