Dystrybutor Fluks Facebooka explicitly prohibits ActionCreators from dispatching other ActionCreators. To zastrzeżenie jest prawdopodobnie dobrym pomysłem, ponieważ zapobiega tworzeniu przez aplikację łańcuchów zdarzeń.Unikanie łańcuchów zdarzeń z asynchronicznymi zależnościami danych
To jednak staje się problemem, gdy tylko masz Sklepy zawierające dane z asynchronicznych ActionCreatorów zależnych od siebie. Jeśli CategoryProductsStore
zależy od CategoryStore
, nie wydaje się, aby można było uniknąć łańcuchów zdarzeń, nie odwołując się do dalszych działań.
Scenariusz 1: Sklep zawierający listę produktów w kategorii musi wiedzieć, z jakiej kategorii należy pobrać identyfikator produktów.
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)
...
Scenariusz 2: Inny scenariusz jest, gdy składnik dziecko jest zamontowany w wyniku zmiany Store i jego 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)
}
}
})
Czy istnieją sposoby, aby tego uniknąć bez uciekając się odroczyć?
Dla scenariusza nr 1, umieściłem tego rodzaju logikę w samych twórcach akcji, tak aby sklepy reagowały tylko na zmiany danych. W przypadku, gdy istnieje logika asynchroniczna, twórca akcji będzie czasami wysyłał wiele akcji do sklepów. Wpadłem na scenariusz nr 2 i przełączyłem się na 'DidMount' (w przypadku asynchronicznego wczytywania danych) lub od czasu do czasu odroczyłem od' setTimeout'. –
@BrandonTilley Objaśniłem oba przykłady, w obu przypadkach ActionCreator, aby pobrać produkty w kategorii, uruchamia asynchroniczną operację interfejsu API. –
@SimenBrekken czy rozwiązałeś swój problem? Można spojrzeć tutaj: http://support.microsoft.com/questions/32537568/flux-waitfor-specific-event? –