Facebook Flux 调度程序明确禁止 ActionCreators 调度其他 ActionCreators。这种限制可能是一个好主意,因为它会阻止您的应用程序创建事件链。
但是,一旦您的 Store 包含来自相互依赖的异步 ActionCreators 的数据,这就会成为一个问题。如果CategoryProductsStore
依赖于CategoryStore
,似乎没有办法在不采取推迟后续行动的情况下避免事件链。
场景 1: 包含某个类别中产品列表的商店需要知道它应该从哪个类别 ID 获取产品。
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:
另一种场景是当一个子组件作为 Store 更改的结果被挂载并且它 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)
}
}
})
有没有办法避免这种情况而不诉诸延迟?