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