如何在 Redux 中有条件地分发 / "cascade" 操作
How to conditionally-dispatch / "cascade" actions in Redux
我正在开发一个 vanilla-js 应用程序(独立的 UI 组件),我一直在尝试使用 Redux 来使一些逻辑更容易测试和推理。
有一个 UI 事件/用户操作(我们称之为 "DO_SOMETHING_ACTION"),可以在 UI:
中以多种不同的方式触发
- 通过按键
- 通过鼠标拖动
对于#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>);
});
});
我正在开发一个 vanilla-js 应用程序(独立的 UI 组件),我一直在尝试使用 Redux 来使一些逻辑更容易测试和推理。
有一个 UI 事件/用户操作(我们称之为 "DO_SOMETHING_ACTION"),可以在 UI:
中以多种不同的方式触发- 通过按键
- 通过鼠标拖动
对于#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>);
});
});