Evitar cadenas de eventos con dependencias de datos asincrónicas

El despachador de Facebook Fluxprohíbe explícitamente que ActionCreators envíe otros ActionCreators. Esta restricción es probablemente una buena idea, ya que evita que su aplicación cree cadenas de eventos.

Sin embargo, esto se convierte en un problema a medida que tiene tiendas que contienen datos de ActionCreators asincrónicos que dependen unos de otros. SiCategoryProductsStore depende deCategoryStore no parece haber una manera de evitar cadenas de eventos cuando no se recurre a diferir la acción de seguimiento.

Escenario 1: Una tienda que contiene una lista de productos en una categoría necesita saber de qué ID de categoría debe buscar productos.

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)

      ...

Escenario 2: Otro escenario es cuando se monta un componente hijo como resultado de un cambio de Tienda y sucomponentWillMount/componentWillReceiveProps intenta obtener datos a través de un ActionCreator asíncrono:

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)
    }
  }
})

¿Hay formas de evitar esto sin recurrir a diferir?

Respuestas a la pregunta(2)

Su respuesta a la pregunta