ReactJS + Fluxxor级联操作会导致错误

时间:2015-09-30 12:45:49

标签: javascript reactjs reactjs-flux flux

我有一个包含2个子组件的父组件;

更新
我已经重写了一些语句和代码,以使其更容易理解。

家长:ReservationFormComponent
儿童:ReservationTypePanel& ReservationCalendarPanel

父组件ReservationFormComponent最初仅显示ReservationTypePanel。在ReservationCalendarPanel上选择某个项目之前,其他同级ReservationTypePanel将被隐藏。

所以问题是当ReservationTypePanel中选择了一个项目时,ReservationCalendarPanel会使用ReservationFormStore商店中设置的初始值进行呈现。特别

    initialize: function(){
      this.reservationType = void 8;
      this.pickupTime = moment().add('minutes',30);
    }

因此,当呈现ReservationCalendarPanel时,接受状态DateTimeField的子组件pickupTime将重新呈现并触发onChange事件,该事件需要执行其他操作

    return DateTimeField({
      pickupTime: pickupTime,
      onChange: function(time){
        // Here is where the action gets called again
        this$.getFlux().actions.setReservationPickupTime(time);
      }
    });

使用此错误Uncaught Error: Cannot dispatch an action while another action is being dispatched

向我致意

我已尽力减少以下代码。我没有使用JSX因为原始代码在LiveScript中,所以我只是将编译后的代码显示在此处。

这是父组件ReservationFormComponent

ReservationFormComponent = React.createClass({
    get flux(){ // Instantiating Fluxxor
      return new Fluxxor.Flux({ // These are the stores
        'reservation-form': new ReservationFormStore,
        'reservation-types': new ReservationTypeStore
      }, { // These are the 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(){ // This triggers the re-render to display the 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 // This conditional to mount or not mount the component
        );
    }

});

ReservationTypePanel组件。这里,呈现的组件侦听onClick事件并调度setReservationType动作。

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);
    })
  }
});

ReservationCalendarPanel组件。这是DateTimeField的呈现位置,它从ReservationFormStore接收状态并设置导致另一个分派的值。这就是错误发生的地方。

ReservationCalendarPanel = React.createClass({
  mixins: [fluxxor.FluxMixin(react)],
  getInitialState: function() {
      return {pickupTime: moment()} // sets the 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 is where the action gets called again
        this$.getFlux().actions.setReservationPickupTime(time);
      }
    });
});

这是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 is no change between the date that
      // is about to be set then just ignore and
      // keep the 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'
    }));
  }
});

如果以下是商店:

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');
    }
});

0 个答案:

没有答案