Facebook Flux调度器
explicitly prohibits ActionCreators from dispatching other ActionCreators.这个限制可能是一个好主意,因为它阻止您的应用程序创建事件链.
@H_404_18@
每当您检索应用程序的状态时,您都可以使用getter方法从商店直接检索该状态.操作是通知商店的对象.你可以认为他们像是要求改变状态.他们不应该返回任何数据.它们不是您应该检索应用程序状态的机制,而只是改变它.
只要您具有包含彼此依赖的异步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:
另一种情况是由于存储更改的结果安装了子组件,并且其组件为WillMount / 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) } } })
有没有办法避免这种情况呢?
所以在场景1中,getCurrent(category.id)是应该在Store上定义的东西.
在场景2中,您似乎正在遇到存储数据初始化问题.我通常(理想情况下)在渲染根组件之前将数据存入商店来处理.我在自举模块中这样做.或者,如果这绝对需要异步,您可以创建一切使用空白板条,然后在商店响应INITIAL_LOAD操作后重新渲染.