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

setState callback in componentWillMount? #1740

Closed
matthewwithanm opened this issue Jun 25, 2014 · 15 comments
Closed

setState callback in componentWillMount? #1740

matthewwithanm opened this issue Jun 25, 2014 · 15 comments

Comments

@matthewwithanm
Copy link
Member

Calling setState in componentWillMount doesn't behave as I would expect. Here's a fiddle demonstrating. In short, the callback is invoked before the state has been updated.

@sophiebits
Copy link
Collaborator

In master the callback isn't called immediately but it looks like we have a bug where it's not called at all (which you can repro by using http://react.zpao.com/builds/master/latest/react-with-addons.js on JSFiddle).

@langpavel
Copy link

👻

@sbrandwoo
Copy link

It would appear that this is still a bug but it's behaviour has changed since the bug was opened.

In 0.10.0 the callback is called too soon, before the state has changed (http://jsbin.com/cuyadiqojumi/1/edit).
In 0.11.0 the callback is never called (http://jsbin.com/senasemurifa/1/edit).

@sbrandwoo
Copy link

In 0.12.1 this callback is never called (http://jsbin.com/pedexogoxe/1/edit?js,console,output)

@fredkelly
Copy link

Is there an interim solution to get the desired behaviour?

@bobiblazeski
Copy link

Any update on this still happening on 0.13.1 http://jsfiddle.net/28zsnwcb/2/

@ccorcos
Copy link

ccorcos commented May 14, 2015

This is super annoying. I think this ought to work as well: http://jsfiddle.net/5L9u5oqz/1/

@jbpros
Copy link

jbpros commented Jul 14, 2015

Running into this problem as well.

@ccorcos
Copy link

ccorcos commented Jul 14, 2015

Now I'm getting an issue where the callback isnt being called at all. Oy vey

http://codepen.io/ccorcos/pen/QbxaMg

@ccorcos
Copy link

ccorcos commented Jul 14, 2015

@matthewwithanm Here's your same JSFiddle with an updated version of React and the callback never gets called! WTF!

http://jsfiddle.net/ccorcos/k5ws12c6/

P.S. Just noticed that other people have mentioned this as well

@brigand
Copy link
Contributor

brigand commented Jul 14, 2015

If you need something for now, you can use this function to patch it.

var Hello = React.createClass({
    getInitialState: function() { return {}; },
    componentWillMount: function() {
        hotfixSetState(this);
        this.setState({testing: '123'}, function() { ... });
    }
    // ...
});


function hotfixSetState(instance){
    var original = {
        componentWillMount: instance.componentWillMount,
        setState: instance.setState,
        componentDidMount: instance.componentDidMount
    };
    var traced = new Error();

    var callbacks = [];
    var isMounted = false;

    instance.setState = function(update){
        var callback = arguments[1];
        if (callback) {
            callbacks.push(callback);
        }

        // don't pass the callback
        original.setState.call(instance, update, function(){
            console.warn('you are using hotfixSetState, but the setState callback was called', traced, instance);
        });
    };

    instance.componentWillMount = function(){
        if (original.componentWillMount) {
            return original.componentWillMount.apply(this, arguments);
        }
    };

    instance.componentDidMount = function(){
        for (var i=0; i<callbacks.length; i++) {
            callbacks[i].call(undefined);
        }
        instance.setState = original.setState;

        if (original.componentDidMount) {
            return original.componentDidMount.apply(instance, arguments);
        }
    };
};

@ccorcos
Copy link

ccorcos commented Jul 15, 2015

you da man!

@sophiebits
Copy link
Collaborator

#4171 should have fixed this. The callback fires on the client but not the server.

@gaearon
Copy link
Collaborator

gaearon commented Mar 23, 2016

If it is fixed, is this comment outdated?

// TODO: The callback here is ignored when setState is called from
// componentWillMount. Either fix it or disallow doing so completely in
// favor of getInitialState. Alternatively, we can disallow
// componentWillMount during server-side rendering.
enqueueUpdate(internalInstance);

@LiuuY
Copy link

LiuuY commented Jul 19, 2016

Recently I am reading the source code about batching, this comment really make me confused, until I find this issue, maybe you guys can delete it?

// TODO: The callback here is ignored when setState is called from
// componentWillMount. Either fix it or disallow doing so completely in
// favor of getInitialState. Alternatively, we can disallow
// componentWillMount during server-side rendering.
enqueueUpdate(internalInstance);

cvburgess added a commit to PerchSecurity/perch-data that referenced this issue Dec 5, 2017
cvburgess added a commit to PerchSecurity/perch-data that referenced this issue Dec 5, 2017
Had to switch to lifecycle methods because of
facebook/react#1740 (or so I think)
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