Избегание цепочек событий с асинхронными зависимостями данных

Диспетчер потока Facebookпрямо запрещает ActionCreators отправлять других ActionCreators, Это ограничение, вероятно, хорошая идея, так как оно не позволяет вашему приложению создавать цепочки событий.

Это, однако, становится проблемой, как только у вас есть Хранилища, содержащие данные от асинхронных ActionCreators, которые зависят друг от друга. ЕслиCategoryProductsStore зависит отCategoryStore Кажется, не существует способа избежать цепочки событий, если не прибегать к отсрочке последующих действий.

Сценарий 1: Магазин, содержащий список товаров в категории, должен знать, из какого идентификатора категории он должен получать товары.

var CategoryProductActions = {
  get: function(categoryId) {
    Dispatcher.handleViewAction({
      type: ActionTypes.LOAD_CATEGORY_PRODUCTS,
      categoryId: categoryId
    })

    ProductAPIUtils
      .getByCategoryId(categoryId)
      .then(CategoryProductActions.getComplete)
  },

  getComplete: function(products) {
    Dispatcher.handleServerAction({
      type: ActionTypes.LOAD_CATEGORY_PRODUCTS_COMPLETE,
      products: products
    })
  }
}

CategoryStore.dispatchToken = Dispatcher.register(function(payload) {
  var action = payload.action

  switch (action.type) {
    case ActionTypes.LOAD_CATEGORIES_COMPLETE:
      var category = action.categories[0]

      // Attempt to asynchronously fetch products in the given category, this causes an invariant to be thrown.
      CategoryProductActions.get(category.id)

      ...

Сценарий 2: Другой сценарий - это когда дочерний компонент монтируется в результате изменения хранилища и егоcomponentWillMount/componentWillReceiveProps пытается получить данные через асинхронный ActionCreator:

var Categories = React.createClass({
  componentWillMount() {
    CategoryStore.addChangeListener(this.onStoreChange)
  },

  onStoreChange: function() {
    this.setState({
      category: CategoryStore.getCurrent()
    })
  },

  render: function() {
    var category = this.state.category

    if (category) {
      var products = <CategoryProducts categoryId={category.id} />
    }

    return (
      <div>
        {products}
      </div>
    )
  }
})

var CategoryProducts = React.createClass({
  componentWillMount: function() {
    if (!CategoryProductStore.contains(this.props.categoryId)) {
      // Attempt to asynchronously fetch products in the given category, this causes an invariant to be thrown.
      CategoryProductActions.get(this.props.categoryId)
    }
  }
})

Есть ли способы избежать этого, не прибегая к отсрочке?

Ответы на вопрос(2)

Ваш ответ на вопрос