我有一个 redux 应用程序,它是一个带有页面的调查。为了更改页面,我有一个 NAVIGATION_NEXT_PAGE 操作。然后,Reducer 会处理存储中新页面的创建。我还有很多其他操作可以设置问题答案,甚至可以浏览页面。在通过 NAVIGATION_NEXT_PAGE 显示的每个新页面中,我都有一个用户定义的操作列表,当页面首次显示和回答问题时要执行。
我的问题是如何在每次显示新页面时递归地分派(dispatch)操作,同时仍然将操作逻辑与组件解耦。我不想在 PageContainer 中分派(dispatch)操作,因为如果操作要求跳过页面,我根本不希望显示该页面。
这是我当前的解决方案:
const actionMiddleware = (store) => (next) => (action) => {
// Execute post answer actions on the current page.
switch (action.type) {
case types.NAVIGATION_NEXT_PAGE:
for (let postAnswerAction of store.getState().postAnswerActions);
next(store.dispatch(actionFromPageAction(postAnswerAction)))
break;
}
// Evaluate the action.
let result = next(action);
// Execute the preload actions of the new page.
switch (action.type) {
case types.NAVIGATION_NEXT_PAGE:
for (let preLoadAction of store.getState().preLoadActions);
next(store.dispatch(actionFromPageAction(preLoadAction)))
break;
}
return result;
};
但它引入了奇怪的行为,因为有时 react 不会更新我的用户界面。也许我的中间件破坏了react-redux?
我走在正确的道路上吗?从中间件分派(dispatch)操作的正确方法是什么?
最佳答案
你可以为此制定一个自制的解决方案,但我强烈不推荐这样做。下面的这个示例结合了一堆函数,这些函数能够根据给定的操作和存储返回新的操作。 (我没有测试过,但理论上它可能有效)
const actionTransformerMiddleware = (...transformers) => store => next => inAction => {
transformers.map(transformer => transformer(inAction, store))
.filter(output => !!output) // checking if non null undefined or empty array
.forEach(actions =>
// Here alternatively you could store.dispatch these, then the new actions
// go through the same action transformers, but you won't be able
// to return an identical action, since that would cause an endless cycle.
(Array.isArray(actions) ? actions : [actions]).forEach(action => next(action))
)
}
const whateverActionTransformer = (action, store) => {
const {postAnswerActions, preLoadActions} = store.getState()
switch (action.type) {
case types.NAVIGATION_NEXT_PAGE:
return (postAnswerActions || []).concat(preLoadAction || [])
}
}
const myActionMiddleware = actionTransformerMiddleware(
whateverActionTransformer,
// here more of these could come... but maybe they shouldn't?
)
但是,我在您发布的示例中看到了一些代码味道(它们在我的示例中也完好无损)。
为什么要在商店中存储操作?为什么不单独 dispatch 他们?如果这不可行,为什么不调度一个仅包含这些操作携带的有效负载的操作,让 thunk 执行并组合所有结果并为您提供一个输出?
关于javascript - 如何根据其他操作的结果对操作进行排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41815342/