Flux模式初始化Store

时间:2015-03-30 15:59:21

标签: reactjs reactjs-flux

早安全部!

我有一个依赖于商店的反应组件(一个视图),而该商店依赖于从往返服务器中拉出一些状态。

我想要了解的是,如果有一个常见的模式可以解决初始化商店的状态。

现在我想我会做类似的事情:

var SomeView = React.createClass({
  componentWillMount: function() {
    SomeStore.addChangeListener(this._onChange);

    // Go and tell this thing we want to initiliaze our
    // state ahead of time. My worry here is obviously 
    // that when state is updated this fires again so I'd
    // need to have some knowledge that the store has been
    // initialized which seems very (very) kludgey
    SomeActions.init();
  },

  render: function() {
    // Here i'd want to see if I had items available for
    // rendering. If I didn't I'd drop on a loading dialog
    // or if I did I could render the detail.
  },

  _onChange: function() {
     // this.setState...
  }
});


var SomeActions = {
  init: function() {
    AppDispatcher.dispatch({
      actionType: SomeConstants.INIT
    });
  }
};


var SomeStore = assign({}, EventEmitter.prototype, { 
  init: function() {
    $.get('/round/trip', function(data) {
      this.emitChange();
    }).bind(this);
  }

  emitChange: function() {
    this.emit(CHANGE_EVENT);
  },

  addChangeListener: function(callback) {
    this.on(CHANGE_EVENT, callback);
  }
});


AppDispatcher.register(function(action) {
  switch(action.actionType) {
    case SomeConstants.INIT:
      SomeStore.init()
      break;

    default:
  }
});

我绝对肯定必须有更好的方法。

1 个答案:

答案 0 :(得分:1)

  

我的担心显然是当状态更新时再次激发

componentWillMount一旦组件注入DOM就触发,状态更新不会触发此方法。但是,如果从DOM中删除组件(例如:不根据某些条件在父组件中呈现它)并稍后再渲染它,则将再次触发该方法。因此,init将在商店中多次调用。

我相信您应该将http请求代码移动到Web API模块并从componentWillMount方法向API激活操作,然后API将触发存储并在组件上触发change事件,将更新状态并重新渲染。这就是Flux的工作原理。

如果您只需要获取一次数据并且您知道您的组件将多次从DOM中删除/添加到DOM中,您应该将api调用到树中的上部组件(表示入口点的组件)小部件或其他东西)。

我建议检查Component Container或更高阶组件模式,它基本上将瘦包装器组件定义为视图组件上的数据层。因此,您可以将视图与数据层完全分开,并且效果很好。

您可能还想检查另一种方法,来自ClojureScript& Om,具有单一的不可变状态。这简化了一切,实际上是我通过React构建应用程序的最佳方式。我为它创建了a starter kit,对自述文件中的主要概念有一个很好的解释。