Sim*_*ken 13 reactjs reactjs-flux
Facebook Flux调度员明确禁止ActionCreators派遣其他ActionCreator.这种限制可能是一个好主意,因为它会阻止您的应用程序创建事件链.
但是,只要存储包含异步ActionCreator中彼此依赖的数据的存储,就会出现问题.如果不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)
...
Run Code Online (Sandbox Code Playgroud)
场景2:
另一种情况是,当存储更改及其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)
}
}
})
Run Code Online (Sandbox Code Playgroud)
有没有办法避免这种情况而不诉诸推迟?
每当您检索应用程序的状态时,您都希望使用 getter 方法直接从 Store 检索该状态。操作是通知存储的对象。您可以将它们视为状态更改的请求。他们不应该返回任何数据。它们不是您检索应用程序状态的机制,而只是更改它。
因此,在场景 1中,getCurrent(category.id)是应该在 Store 上定义的内容。
在场景 2中,听起来您遇到了 Store 数据初始化的问题。我通常通过(理想情况下)在渲染根组件之前将数据放入存储中来处理这个问题。我在引导模块中执行此操作。或者,如果这绝对需要异步,您可以创建所有内容以使用空白板,然后在商店响应操作后重新渲染INITIAL_LOAD。
| 归档时间: |
|
| 查看次数: |
1853 次 |
| 最近记录: |