我正在考虑围绕redux的一些场景,我无法找到这个例子的干净解决方案:
假设您有一个组件列表。当您从该列表中选择食谱时,您dispatch(RECIPE_SELECTED)
。那个异步动作创建者可以做一些与配方有关的附加内容 - 也许是异步获取配方的成分,将选择保存到服务器,无论如何。
在一个完全独立的组件中,您有一份专业厨师名单。期望的行为是,当用户选择食谱时,您可以使用任何具有所选食谱变体的厨师填充专业厨师列表。
你如何监听RECIPE_SELECTED
,然后发送一个完全不相关的动作,这个动作依赖于食谱?有点像...
when RECIPE_SELECTED:recipe
loadChefs(recipe).then(res => dispatch(CHEFS_LOADED, res.chefs))
你可以将这个loadChefs/dispatch
混合到RECIPE_SELECTED
的动作创建者中,但这是一个非常混乱的问题,并会很快编织出一个纠结的网络。
你也可以做一些非常必要的事情(即针对redux的谷物)这样的东西(使用React):
componentWillReceiveProps(nextProps) {
if (nextProps.recipe !== this.props.recipe) {
const { dispatch, recipe } = nextProps
dispatch(loadChefs(recipe))
}
}
我真的不喜欢这两种解决方案。想法?
答案 0 :(得分:4)
你熟悉redux-thunk吗? https://github.com/gaearon/redux-thunk
将redux-thunk应用为中间件,你可以这样做:
function selectRecipe(recipe) {
return function (dispatch) {
dispatch(setRecipe(recipe));
return loadChefs(recipe).then((res) =>
dispatch(setChefs(res.chefs))
);
};
}
setRecipe
和setChefs
是简单的动作创作者。 e.g。
function setRecipe(recipe) {
return {
type: SET_RECIPE,
recipe
};
}
function setChefs(chefs) {
return {
type: SET_CHEFS,
chefs
};
}
我建议您阅读有关Async Actions的文档。 https://redux.js.org/advanced/async-actions
答案 1 :(得分:0)
另一种解决方案是使用Redux-Saga中间件。这可以让你写这样的东西:
function* loadChefsSaga() {
# takeLatest sets up a system that spawns the inner generator every time
# an action matching the pattern is dispatched. If the inner generator
# is still running when additional actions are dispatched, it is cancelled,
# and a new one is spawned.
yield takeLatest('RECIPE_SELECTED', function* (recipe) {
# When a Promise is yielded, the generator is resumed when the Promise
# resolves. Alternatively, if it rejects, the rejected value is thrown
# into this generator.
const {chefs} = yield loadChefs(recipe)
# Assuming chefsLoaded is an action creator for CHEFS_LOADED
# `put` is redux-saga's equivelent of `dispatch`. We use it because
# the saga doesn't have direct access to the `dispatch` function.
yield put(chefsLoaded(chefs))
})
}
我假设您已基本熟悉javascript生成器的工作方式。如果没有,去看看吧;他们是一个强大的模式。在这种情况下,redux-saga使用它们来构造可以阻止事物的函数。每次产生某些东西,redux-saga都会将其视为一种效果"它知道如何处理。例如,当产生Promise
时,redux-saga将其设置为当Promise解析时生成器恢复(或者如果它拒绝则抛出某些东西)。