每次在本地缓存数据时,Reflux都会避免命中服务器

时间:2015-08-11 14:12:12

标签: javascript reactjs refluxjs

我很好奇是否有任何商定的模式来检查数据是否已经在加入服务器之前已经加载。

说我的动作看起来像这样:

Actions.loadRequest.preEmit = function () {
  $.get('/store/', function (data) {
      Actions.loadSuccess(data);
  }.bind(this));
}

这是从一个只是说给我这个数据的组件调用的: 但如果该数据已经存储在商店中,我不想点击服务器。 我应该在组件中存储检查商店的逻辑:

render: function () {
  var data = this.state.store.data;
  if (!data) {
    Actions.loadRequest();
  }

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

在我的项目中,我使用shouldEmit(请参阅https://github.com/reflux/refluxjs#action-hooks)。我的代码中的一个例子:

var streamStore = Reflux.createStore({
    [...]
});

actions.loadStream.shouldEmit = function(streamId) {
    if(streamId in streamStore.data)
        return false;
    return true;
};

它与商店定义位于同一文件中。我认为这在概念上是正确的方法,因为商店会保存数据,因此商店应该负责拦截加载更多数据的请求而不是说,就像它负责听取更多数据的操作一样可用并自行更新。

不幸的是,这不适用于您的示例,因为您将AJAX调用绑定到preEmit,在shouldEmit之前调用它。我建议重构以正常的listen调用方式调用API,如下所示:

Actions.loadRequest.listen(function () {
  $.get('/store/', function (data) {
      Actions.loadSuccess(data);
  }.bind(this));
});

这可以节省preEmit,以便在发出动作之前需要重写动作的参数。我在我的代码中使用了这种模式,例如在加载第二页结果时,它依赖于第一页附带的next令牌,因此在商店中。但是在触发操作的一般简单情况下,使用listen发出请求更有意义,因为这样您可以添加preEmitshouldEmit以获得更高级行为,就像你想要的缓存一样。

Reflux还有一个辅助函数listenAndPromise,它进一步简化了"动作触发的常见用例,进行AJAX调用,然后在完成时触发另一个动作"。你的例子可能变成:

Actions.loadRequest.listenAndPromise(function () {
    return $.get('/store/');
});    

有关如何设置该文档的更多信息,请参阅文档的此部分:https://github.com/reflux/refluxjs#asynchronous-actions