javascript - ReactJS + Fluxxor cascading actions causes error -
i've got parent component has 2 child components;
update
i've rewritten statements , code make more understandable.
parent: reservationformcomponent
children: reservationtypepanel & reservationcalendarpanel
the parent component reservationformcomponent displays reservationtypepanel only. other sibling reservationcalendarpanel hidden until item selected on reservationtypepanel.
so problem when item selected in reservationtypepanel reservationcalendarpanel rendered initial values set in reservationformstore store. particularly
initialize: function(){ this.reservationtype = void 8; this.pickuptime = moment().add('minutes',30); } so when reservationcalendarpanel rendered, child component datetimefield accepts state pickuptime re-rendered , fires onchange event calls action
return datetimefield({ pickuptime: pickuptime, onchange: function(time){ // here action gets called again this$.getflux().actions.setreservationpickuptime(time); } }); and greets me error uncaught error: cannot dispatch action while action being dispatched
i've tried best trim down codes below. wasn't using jsx because original code in livescript took compiled code display here instead.
this parent component reservationformcomponent
reservationformcomponent = react.createclass({ flux(){ // instantiating fluxxor return new fluxxor.flux({ // these stores 'reservation-form': new reservationformstore, 'reservation-types': new reservationtypestore }, { // these actions setreservationtype: function(value){ return this.dispatch('set_reservation_type', value); }, setreservationpickuptime: function(value){ return this.dispatch('set_reservation_pickup_time', value); } }); }, componentwillmount: function(){ this.flux.store('reservation-form').addlistener('change', this.onchange); }, onchange: function(){ // triggers re-render display reservationcalendarpanel this.setstate({ pickuptime: this.flux.store('reservation-form').pickuptime }); }, render: function() { reservationtype = this.state.reservationtype; return form({ classname: 'container' }, reservationtypepanel({ flux: this.flux }), reservationtype ? reservationcalendarpanel({ flux: this.flux }) : null // conditional mount or not mount component ); } }); the reservationtypepanel component. here, rendered component listens onclick event , dispatches setreservationtype action.
reservationtypepanel = react.createclass({ mixins: [fluxxor.fluxmixin(react)], onselectreservationtype: function(reservationtype){ var this$ = this; return function(event){ this$.getflux().actions.setreservationtype(reservationtype); }; }, render: function() { var this$ = this; return reservationtypeitem({ onclick: this$.onselectreservationtype(type); }) } }); the reservationcalendarpanel component. here datetimefield rendered , receives state reservationformstore , sets value causes dispatch. error comes.
reservationcalendarpanel = react.createclass({ mixins: [fluxxor.fluxmixin(react)], getinitialstate: function() { return {pickuptime: moment()} // sets current time }, componentwillmount: function(){ this.getflux().store('reservation-form').addlistener('change-pickup-time', this.onflux); }, componentwillunmount: function(){ this.getflux().store('reservation-form').removelistener('change-pickup-time', this.onflux); }, render: function() { var this$ = this; if (this.state.pickuptime) { pickuptime = moment(this.state.pickuptime); } return datetimefield({ date: pickuptime, onchange: function(time){ // here action gets called again this$.getflux().actions.setreservationpickuptime(time); } }); }); this datetimefield
datetimefield = react.createclass({ getinitialstate: function(){ return { text: '' }; }, componentwillreceiveprops: function(nextprops){ this.setdate(nextprops.date); }, componentdidmount: function(){ $(this.getdomnode()).datepicker() .on('changedate', this.onchangedate) .on('cleardate', this.onchangedate); this.setdate(this.props.date); }, componentwillunmount: function(){ return $(this.getdomnode()).datepicker('remove'); }, getdatepickerdate: function(){ return $(this.getdomnode()).datepicker('getdate'); }, setdate: function(date){ if (!this.ismounted()) { return; } if (moment(date).issame(this.getdatepickerdate, 'day')) { // if there no change between date // set ignore , // keep old one. return; } date = date ? moment(date).todate() : void 8; $(this.getdomnode()).datepicker('setdate', date); }, onchangedate: function(event){ if (this.props.onchange) { this.props.onchange(event.date); } }, render: function(){ return this.transferpropsto(input({ type: 'text', classname: 'form-control' })); } }); if in case here store:
reservationformstore = fluxxor.createstore({ actions: { set_reservation_type: 'setreservationtype', set_reservation_pickup_time: 'setpickuptime' }, initialize: function(){ this.reservationtype = void 8; this.pickuptime = moment().add('minutes',30); }, setreservationtype: function(reservationtype){ this.reservationtype = reservationtype; this.reservationtypevalidate = true; this.emit('change-reservation-type', this.reservationtype); this.emit('change'); } setpickuptime: function(pickuptime){ this.pickuptime = pickuptime; this.pickuptimevalidate = true; this.emit('change-pickup-time', this.pickuptime); this.emit('change'); } });
Comments
Post a Comment