我想知道如何管理reducer之间的依赖关系。
假设你触发了一些动作,并且有两个reducer在"监听"这个动作,但是你希望其中一个在另一个之前运行。
的例子:你有减量的配料和减量的膳食(膳食由配料组成)。每个reducer都从服务器获取数据,从中生成cast对象并将其保存在存储中(例如,components reducer生成一个Ingredient对象数组并将其作为新状态返回)。每种成分都有一个唯一的id。Meal of在构造函数中获取一个listingredients id(它包含的成分),然后从存储中获取相关的成分对象,并将它们作为Meal的属性添加。出于效率的考虑,我们从服务器(一个GET请求)一起获取所有数据(配料和饭菜)。当你触发FETCH_ALL_DATA_FROM_SERVER(以获取的数据作为有效负载)时——你想让配料和饭菜减少器都"听"到这个动作:
- 配料减速器应该解析配料的原始信息从服务器提取到cast Ingredient对象,并存储
- 膳食减速器应该解析获取的膳食原始信息从服务器转换成强制转换Mael对象,并将它们存储在商店。
但这里是它变得棘手的地方-如果餐减速器试图创建一个餐对象,其中包含的成分还没有在商店(成分减速器还没有加载到商店)?
我该如何解决这个问题?提前感谢:)
更新
代码示例:抓取操作看起来像这样:
export function fetchAllDataFromDB() {
return dispatch => {
axios.get('http://rest.api.url.com')
.then(response => {
dispatch({
type: FETCH_ALL_DATA_FROM_DB,
payload: response.data
})
})
.catch(error => {
console.log(error)
})
}
}
配料减速器看起来是这样的:
export default function reducer(state={}, action) {
switch (action.type) {
case FETCH_ALL_DATA_FROM_DB: {
// Create the Ingredient objects from the payload
// They look like Ingredient(id, name, amount)
}
}
return state
}
减餐器看起来是这样的:
export default function reducer(state={}, action) {
switch (action.type) {
case FETCH_ALL_DATA_FROM_DB: {
// Create the Meal objects from the payload
// They look like Meal(id, name, price, ingredients_ids)
// It will try to fetch the ingredients (of ingredients_ids) from the store - and fail, because hey are not there yet.
}
}
return state
}
问题是-在配料减速器完成将相关配料加载到存储之前,您不能创建Meal对象。
更新
我还没有真正解决这个问题,但我所做的是:我更改了Meal构造函数,这样它就不会从存储中获取Ingredient对象,而是坚持使用配料s_ids列表。我还添加了一个getter,用于从store中获取Meal对象。这样可能会更好,因为现在我可以动态地改变一顿饭的成分(不是我想…)。但效率较低……如果你能找到更好的解决办法,我很想知道。
谢谢你的帮助
我想你可以搜索更多关于javascript异步的主题。
如果您希望在运行另一个方法之前等待2个或更多操作完成,则通常使用。你可以使用Promise.all(),或将回调嵌套到回调地狱或使用async.series()库。回到redux,您可以确保在呈现(dispatch())之前所有队列都已完成运行
我还建议学习Promise而不是async库。
示例:
fetch().then( res => dispatch({type: "I_GET_THE_DATA", payload: res.data}))
如果你愿意,你甚至可以链式获取
fetch(mealURL).then( res1 =>{
fetch(ingredientsURL).then(res2 => {
var meal_and_ingredients = {
meal: res1,
ingredients: res2
}
dispatch({type: "GET_TWO_DATA", payload: meal_and_ingredients})
})
})