[SOLVED] This.setState hanging

I’m running into a really weird issue, where this.setState is causing my app to hang. I can’t really share too much code as I could get in trouble for doing so, but the relevant section is:

        debugMode && console.dir(finalResults);
        Events.remove({}); // clear out any data first
        _.sortBy(finalResults, 'StartDateTime').forEach(function (event) {
          Events.insert(event);
        }); debugger;

        this.setState({
          queryDone: true,
          queryInProgress: false
        });

this.setState is called, and it gets to some function involving queueing, and then it just stops. queryDone is never set to true, and if I put a console.log statement after this.setState, it never gets reached. Something really strange is going on!

Where is this code? Inside an event handler?

Ok, so my main component (Layout) which is always present, has a mixin I made called ActionHandler.

ActionHandler = {
  actions: {
    'ACTION_GET_APPTS': function () {
      let queryStr, queryPromise;
      let finalResults = [];

      this.setState({
        queryDone: false,
        queryInProgress: true
      });

      queryStr = `SELECT ...`;

      queryPromise = new Promise((resolve, reject) => {
        this.props.jsf.runQuery(queryStr, function (err, result) {
          if (err) {
            console.error(err.errorCode, err.message);
          } else {
            resolve({events: result.records});
          }
        });
      });

      queryPromise.then(val => {
        queryStr = `SELECT ...`; //another query

        return new Promise((resolve, reject) => {
          this.props.jsf.runQuery(queryStr, function (err, result) {
            resolve(_.extend(val, {propertyDetails: result.records}));
          });
        });
      }).then(val => {
        // ... more stuff
        debugMode && console.dir(finalResults);
        Events.remove({}); // clear out any data first
        _.sortBy(finalResults, 'StartDateTime').forEach(function (event) {
          Events.insert(event);
        }); debugger;

        this.setState({
          queryDone: true,
          queryInProgress: false
        });

        // execution never gets here. what?!
      });

    },

    'ACTION_LOGOUT': function () {
      this.props.jsf.logout()
    }
  },

  getInitialState() {
    return {
      queryDone: false,
      queryInProgress: false
    }
  },

  runAction(action, ...args) {
    this.actions[action].call(this, ...args);
  }
};

Hopefully that gives enough context. If I could go back in time, and had I known about meteorflux:dispatcher, I would’ve used that instead of throwing together my own dispatch system. :slight_smile: I still might do that, if I can’t figure this out.

I’m gonna do a git bisect and see if I can go back to see what broke. If it’s a core package, I’ll let you know!

Wow, this makes no sense. I’ve checked out older commits where I know it was working, and those hang as well. I even did rm -rf ~/.meteor and rm -rf .meteor/local to flush anything bad out. I’m stumped. :frowning:

BINGO. I was able to get an actual error by selecting the component in the React devtools and doing $r.setState({queryDone: true}).

react.browserify.js:

  _updateRenderedComponent: function(transaction, context) {
    var prevComponentInstance = this._renderedComponent;
    var prevRenderedElement = prevComponentInstance._currentElement; // ERROR HERE
    var childContext = this._getValidatedChildContext();
    var nextRenderedElement = this._renderValidatedComponent(childContext);

Error:

Uncaught TypeError: Cannot read property ‘_currentElement’ of null(…)

It concerns me that React didn’t throw an error in the console, until I ran setState manually.

Weird. Upgrading to Meteor 1.2.0.2 revealed another error in my code that was not being shown in 1.2.0.1 for some reason. I have no idea why. At any rate, things are fine now! My code was trying to call a String prototype method on a null object.

1 Like