What is the proper way to getInitialState with remote data in Reactjs? -
it solved. code ok, problem improper import.
it long post (due code samples). i'll appreciate patience , thankful help!
we have ror back-end , react on front-end , using alt implementation of flux. use babel compile es6 es5. problem can not render component due 2 errors.
first uncaught typeerror: cannot read property 'map' of undefined
it appears on render function of mappalette component:
render() { return ( <div> {this.state.featurecategories.map(fc => <paletteitemslist featurecategory={fc} />)} </div> ); }
and second uncaught error: invariant violation: receivecomponent(...): can update mounted component.
so here whole mappalette component
"use strict"; import react 'react'; import paletteitemslist './paletteitemslist'; import featurecategorystore '../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 last - how render react component.
var render = function() { featurecategoryactions.getfeaturesetcategories(#{ @feature_set.id }); react.render( react.createelement(featureseteditmap, {featuresetid: #{@feature_set.id}}), document.getelementbyid('react-app') ) }
first of all, first error get:
uncaught typeerror: cannot read property 'map' of undefined
is because this.state
in component undefined, means haven't implemented getinitialstate
in component.
you haven't included full implementation of component, need see able you. let's walk through example of view component:
var locationcomponent = react.createclass({ getinitialstate() { return locationstore.getstate() }, componentdidmount() { locationstore.listen(this.onchange) }, componentwillunmount() { locationstore.unlisten(this.onchange) }, onchange() { this.setstate(this.getinitialstate()) }, render() { return ( <div> <p> city {this.state.city} </p> <p> country {this.state.country} </p> </div> ) } })
they implement getinitialstate
here return current state of store, you'll able use in render
method. in componentdidmount
, listen change events store events occuring in store coming anywhere in application trigger re-render. componentwillunmount
cleans event listener. important not forget this, or app leak memory! next onchange
method (which have whatever name, it's not internal react method), store call when change event occurs. sets state of component whatever stores state is. might bit confusing call getinitialstate
again here, because you're not getting initial state, you're getting current state of store.
another important note here example won't work off bat es6/es2015 classes, because react no longer autobinds methods instance of component. example implemented class this:
class locationcomponent extends react.component { constructor(props) { super(props) this.state = this.getstate(); this.onchangelistener = () => this.setstate(this.getstate()); } getstate() { return locationstore.getstate(); } componentdidmount() { locationstore.listen(this.onchangelistener); } componentwillunmount() { locationstore.unlisten(this.onchangelistener) } render() { return ( <div> <p> city {this.state.city} </p> <p> country {this.state.country} </p> </div> ); } }