javascript - 如何根据其他操作的结果对操作进行排队

标签 javascript redux react-redux

我有一个 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/

相关文章:

javascript - Redux 无法将存储传递给 React 组件

reactjs - 保证发货顺序

reactjs - redux 的好处

javascript - Flow 与 TypeScript Action 创建器 (Redux)

reactjs - 用户信息存放在redux store还是本地存储中?

javascript - 添加从字符串javascript中提取的数字

javascript - ReactJS - 更改另一个组件呈现的内容的组件

javascript - 在数据库中插入两个ID

javascript - 每次单击按钮时使表单中的数字上升

javascript - Jest 单元测试 - 测试 setState()