Il dispatcher di flusso di Facebook explicitly prohibits ActionCreators from dispatching other ActionCreators. Questo restrizione è probabilmente una buona idea poiché impedisce alla tua applicazione di creare catene di eventi.Evitare catene di eventi con dipendenze asincrone dei dati
Questo tuttavia diventa un problema non appena si dispone di archivi contenenti dati da ActionCreators asincroni che dipendono l'uno dall'altro. Se CategoryProductsStore
dipende da CategoryStore
, non sembra essere un modo per evitare le catene di eventi quando non si ricorre a differire l'azione di follow-up.
Scenario 1: Un archivio che contiene un elenco di prodotti in una categoria ha bisogno di sapere da quale ID categoria dovrebbe prendere prodotti.
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)
...
Scenario 2: Un altro scenario è quando un componente figlio è montato come il risultato di un cambiamento Store e la sua componentWillMount
/componentWillReceiveProps
attempts to fetch data via an asynchronous 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)
}
}
})
ci sono modi per evitare questo senza ricorrendo a differire?
Per lo scenario n. 1, inserisco questo tipo di logica nei creatori di azioni, in modo che i negozi rispondano solo alle modifiche nei dati. Nel caso in cui esista una logica asincrona, a volte un action creator invia più azioni ai negozi. Mi sono imbattuto nello scenario n. 2 e ho passato a 'DidMount' (nel caso di caricamento asincrono dei dati), o, occasionalmente, rimandato a' setTimeout'. –
@BrandonTilley Ho chiarito entrambi gli esempi, in entrambi i casi l'ActionCreator per recuperare i prodotti in una categoria attiva un'operazione API asincrona. –
@SimenBrekken hai risolto il tuo problema? Puoi guardare qui http://stackoverflow.com/questions/32537568/flux-waitfor-specific-event? –