不变违规:Dispatch.dispatch(...):无法在调度中间发送

时间:2016-04-04 09:51:59

标签: reactjs react-alt

我在我的ReactJS项目中使用ALT。如果ajax调用尚未完成,我将收到无法“发送”错误,并切换到另一页。

大多数情况下,这就是我的项目设置方式。我有动作,商店和组件。我在componentDidMount生命周期中查询服务器。

动作:

  import alt from '../altInstance'

  import request from 'superagent'
  import config from '../config'

  import Session from '../services/Session'

  class EventActions {
    findNear(where) {
      if (!Session.isLoggedIn()) return
      let user = Session.currentUser();

      request
        .get(config.api.baseURL + config.api.eventPath)
        .query(where)
        .set('Authorization', 'Token token=' + user.auth_token)
        .end((err, res) => {
          if (res.body.success) {
            this.dispatch(res.body.data.events)
          }
        });
    }
  }

  export default alt.createActions(EventActions)

商品

  import alt from '../altInstance'
  import EventActions from '../actions/EventActions'

  class EventStore {
    constructor() {
      this.events = {};
      this.rsvp = {};

      this.bindListeners({
        findNear: EventActions.findNear
      });
    }

    findNear(events) {
      this.events = events
    }

  }

  export default alt.createStore(EventStore, 'EventStore')

组件

  import React from 'react';

  import EventActions from '../../actions/EventActions';
  import EventStore from '../../stores/EventStore';
  import EventTable from './tables/EventTable'

  export default class EventsPage extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        loading: true,
        events: [],
        page: 1,
        per: 50
      }
    }

    componentDidMount() {
      EventStore.listen(this._onChange.bind(this));
      EventActions.findNear({page: this.state.page, per: this.state.per});
    }

    componentWillUnmount() {
      EventStore.unlisten(this._onChange);
    }

    _onChange(state) {
      if (state.events) {
        this.state.loading = false;
        this.setState(state);
      }
    }

    render() {
      if (this.state.loading) {
        return <div className="progress">
          <div className="indeterminate"></div>
        </div>
      } else {
        return <div className="row">
            <div className="col m12">
              <h3 className="section-title">Events</h3>
              <UserEventTable events={this.state.events}/>
            </div>      
        </div>
      }
    }
  }

3 个答案:

答案 0 :(得分:1)

componentDidMount() {
      EventStore.listen(this._onChange.bind(this));
      EventActions.findNear({page: this.state.page, per: this.state.per});
    }

这将是我的猜测。你绑定onChange将触发_onChange中的setState,并且还会从findNear触发一个动作(由于dispatch)。所以可能有一个时刻两者都在同一时刻更新。

首先,我认为findNear应该是componentDidMount中的第一个。

并且还尝试将它分成2个不同的视图(哑和逻辑1,其中第一个仅显示数据,而另一个将进行提取,例如)。同样好的想法也是使用AltContainer来实际避免_onChange动作,由于AltContainer具有相似的东西而且#34;内部&#34;这是非常无用的。

constructor() {
  this.events = {};
  this.rsvp = {};
  this.bindListeners({
    findNear: EventActions.findNear
  });
}

findNear(events) {
  this.events = events
}

我也会在

中重构这个
constructor() {
  this.events = {};
  this.rsvp = {};
}

onFindNear(events) {
  this.events = events
}

Alt有很好的东西,比如自动解析器会查找动作名称+ on,所以如果你有一个名为findNear的动作,它会搜索onFindNear。

答案 1 :(得分:0)

我不明白为什么你会收到这个错误,因为你提供的代码只显示一个动作。

但我的猜测是,您的组件已在系统中的某些其他操作后安装。如果是这样,则错误将由componentDidMount中触发的操作引起。

也许尝试使用Alt的action.defer

componentDidMount() {
    EventStore.listen(this._onChange.bind(this));
    EventActions.findNear.defer({page: this.state.page, per: this.state.per});
}

答案 2 :(得分:0)

我相信它是因为您正在调用某个操作,并且该操作的调度仅在请求完成后才会发生。

我建议将findNear操作拆分为三个操作:findNear,findNearSuccess和findNearFail。

当组件调用findNear时,它应该在提交reuqest之前立即发送,以便相关组件将被更新为正在进行的请求(例如,如果您愿意,则显示加载标记)

并且在同一个动作中,它应该调用另一个动作findNearSuccess。

&#39; Fetching Data&#39;文章应该特别有用。