如何在 Redux 中有条件地分发 / "cascade" 操作

How to conditionally-dispatch / "cascade" actions in Redux

我正在开发一个 vanilla-js 应用程序(独立的 UI 组件),我一直在尝试使用 Redux 来使一些逻辑更容易测试和推理。

有一个 UI 事件/用户操作(我们称之为 "DO_SOMETHING_ACTION"),可以在 UI:

中以多种不同的方式触发
  1. 通过按键
  2. 通过鼠标拖动

对于#1,它很简单 - 我很高兴让 UI 组件确定是否在事件处理程序中按下了适当的键并直接调度 Redux "DO_SOMETHING_ACTION"。

对于 #2,关于我们是否应该调度 "DO_SOMETHING_ACTION" 或 "DO_SOMETHING_ELSE"(或者可能根本不调度)的业务规则 非常复杂 。我希望能够推理测试这个逻辑——因此我的想法是发送一个"MAYBE_DO_SOMETHING"动作(最少从事件处理程序捕获的必要信息 并提取 ).

I/should 我可以通过发送 "MAYBE_DO_SOMETHING" 一个 thunk 来解决这个问题吗?还是我做错了?

肯定可以用一个 thunk 来实现它:

export const dragOverAction = function(payload: DragOverActionPayload) {
  return function(dispatch: Dispatch, getState: () => GlobalStateTree) {
      // Various business logic
      if (someCondition) {
        return;
      }

      if (anotherCondition) {
        dispatch(doSomething({
          <snip>
        }));
      } else if (anotherCondition) {
        dispatch(doSomethingElse({
          <snip>       
        }));
      }

      // Otherwise, don't dispatch anything.
  }
}

测试没有我预期的那么糟糕:

import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";

export const mockStore = configureMockStore([thunk]); 
import * as allActions from "../app/actions/index";

describe("dragOverAction", function() {
    it("should <blah blah>", async function() {
        let store = mockStore();
        await store.dispatch<any>(allActions.dragOverAction({
            foo: bar,
            <snip>
        }));
        const actions = store.getActions();

        expect(actions).toBe(<snip>);
    });
});