Javascript ReactJS+;Fluxxor级联操作导致错误

Javascript ReactJS+;Fluxxor级联操作导致错误,javascript,reactjs,reactjs-flux,flux,Javascript,Reactjs,Reactjs Flux,Flux,我有一个父组件,它有两个子组件 更新 我重写了一些语句和代码,使其更易于理解 父项:ReservationFormComponent 子项:ReservationTypePanel&ReservationCalendarPanel 父组件ReservationFormComponent最初仅显示ReservationTypePanel。另一个同级ReservationCalendarPanel隐藏,直到在ReservationTypePanel上选择了一个项目 因此,问题是当在Reservati

我有一个父组件,它有两个子组件

更新
我重写了一些语句和代码,使其更易于理解

父项:
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);
      }
    });
并向我问候此错误
未捕获错误:无法在发送另一个操作时发送操作

我已经尽力删减了下面的代码。我没有使用
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');
    }
});

看起来每个动作分派都发生在
onChange
处理程序中,因此它们不应该级联,除非
DateTimeField
在呈现后立即调用
onChange
。如果是这种情况,
pickupTime
应该在存储中初始化,并在
ReservationCalendarPanel
中接收,然后以某种方式传递到
DateTimeField
。如果我不正确,请为
DateTimeField
添加代码。您还可以查看是否使用帮助。@BinaryMuse感谢您的回复。似乎
datetime字段
在呈现后立即触发
onChange
事件。我将添加代码。此外,我还重写了问题,并对代码进行了重构,使其更易于理解。请注意,
ReservationCalendarPanel
最初并没有装入,只有在选择了
ReservationTypePanel
中的项目时才会装入。我已经看到了您提到的批量更新,但我正试图找出导致此问题的原因以及解决方法。我目前正在运行
0.10
版本的
React
,因此我无法利用batchUpdate atm。我不确定我是否完全理解您的代码流程,但我注意到有一点可以改进,可能会有所帮助:在
setDate()
函数中,您实际上更改了输入
date
变量,使用语句
date=date?片刻…
。更好:创建一个新的
var tempDate
变量并将其传递给日期选择器。因为
setDate()
也通过
this.props.date
调用,您不应该更改props。