Search code examples
reactjsreactjs-fluxfluxreact-alt

What is the proper way to getInitialState with remote data in Reactjs?


IT IS SOLVED. The code was ok, the problem was with improper import.

It is a long post (due to code samples). I'll appreciate your patience and will be very thankful for your help!

We have a RoR back-end and React on the front-end and we are using alt as an implementation of flux. We also use babel to compile ES6 to ES5. So the problem is that I can not render component due to 2 errors.

First is Uncaught TypeError: Cannot read property 'map' of undefined

It appears on the render function of MapPalette component:

render() {
  return (
    <div>
      {this.state.featureCategories.map(fc => <PaletteItemsList featureCategory={fc} />)}
    </div>
    );
}

And the second is Uncaught Error: Invariant Violation: receiveComponent(...): Can only update a mounted component.

So here is the whole MapPalette component

"use strict";
import React from 'react';
import PaletteItemsList from './PaletteItemsList';
import FeatureCategoryStore from '../stores/FeatureTypeStore';

function getAppState() {
  return {
    featureCategories: FeatureCategoryStore.getState().featureCategories
  };
}

var MapPalette = React.createClass({
  displayName: 'MapPalette',

  propTypes: {
    featureSetId: React.PropTypes.number.isRequired
  },

  getInitialState() {
    return getAppState();
  },

  componentDidMount() {
    FeatureCategoryStore.listen(this._onChange);
  },

  componentWillUnmount() {
    FeatureCategoryStore.unlisten(this._onChange);
  },

  render() {
    return (
      <div>
        {this.state.featureCategories.map(fc => <PaletteItemsList featureCategory={fc} />)}
      </div>
      );
  },

  _onChange() {
    this.setState(getAppState());
  }

});

module.exports = MapPalette;

FeatureCategoryStore

var featureCategoryStore = alt.createStore(class FeatureCategoryStore {
  constructor() {
    this.bindActions(FeatureCategoryActions)
    this.featureCategories = [];
  }

  onReceiveAll(featureCategories) {
    this.featureCategories = featureCategories;
  }

})

module.exports = featureCategoryStore

FeatureCategoryActions

class FeatureCategoryActions {
  receiveAll(featureCategories) {
    this.dispatch(featureCategories)
  }

  getFeatureSetCategories(featureSetId) {
    var url = '/feature_categories/nested_feature_types.json';
    var actions = this.actions;
    this.dispatch();

    request.get(url)
           .query({ feature_set_id: featureSetId })
           .end( function(response) {
             actions.receiveAll(response.body);
           });
  }
}

module.exports = alt.createActions(FeatureCategoryActions);

And the last - how I render React component.

var render = function() {
    FeatureCategoryActions.getFeatureSetCategories(#{ @feature_set.id });
    React.render(
      React.createElement(FeatureSetEditMap, {featureSetId: #{@feature_set.id}}),
      document.getElementById('react-app')
    )
  }

Solution

  • Sorry for your wasted time on reading it, but I figured it out and the reason of trouble was my silly mistake in importing. Essentially, I've imported another Store with the name of needed.

    So, instead of import FeatureCategoryStore from '../stores/FeatureTypeStore';

    It should be import FeatureCategoryStore from '../stores/FeatureCategoryStore';