如何在Redux中分发各种副作用

时间:2018-10-12 08:58:42

标签: reactjs redux

在TypeScript项目中,我向用户显示了一个分支对话框。显示文本并为用户显示选项,然后制定一个新分支。每个分支可能具有一个或多个与之关联的Action,与Redux无关。为了清楚起见,我们将其称为MyAction

MyAction用途广泛,您可以选择要传递的操作类型和参数。该动作对应于在ActionParser中注册的功能,该功能负责执行这些MyAction

最重要的MyAction之一是LOAD_SCENE动作,它使用户可以切换到完全不同的场景。场景首先从服务器加载,然后在对话框树的根分支处呈现给用户。问题就从这里开始。

通常,由于用户单击UI中的按钮而显式加载了场景。调度了Thunk,加载了场景,进行了解析,然后调度了一个动作,通知我们加载成功:

这种情况的发生方式如下:

  1. 用户单击用户界面中的[按钮]
  2. 按钮触发mapDispatchToProps.onButtonClick
  3. onButtonClick调用使用新分支更新SceneParser的函数。
  4. 在选择了新分支之后,onButtonClick会分派动作PARSING_START
  5. 调用
  6. SceneParser.parseActiveBranch,在此执行操作。这是发生副作用的地方。
  7. 最后,调用PARSING_SUCCESS并调用SCENE_UPDATE来显示新的对话框和选项

在步骤5中处理动作。 LOAD_SCENE操作如下所示:

ActionParser.register("LOAD_SCENE", async (args) => {
    if (args.scene) {
        Store.get().dispatch(loadSceneStart());
        await SceneManager.loadScene(args.scene);
        Store.get().dispatch(loadSceneSuccess(SceneManager.activeScene.author));
    } else {
        throw new Error("action 'LOAD_SCENE' requires 'scene' argument");
    }
});

问题很明显:

  1. 场景UI尚未更新-我可以通过在此处添加它来简单地解决此问题,但这也可能导致意外的副作用。
  2. 我正在直接访问商店进行派送,我不知道这是否被认为是一种好习惯,但是肯定感觉不对。

MyAction始终作为业务逻辑的一部分被触发。由于它们可能会产生副作用,因此我希望动作的结果能够影响状态,但是同时,我也不想从动作中分派动作。这是dispatch函数,可以完成所有操作。

public static onSelectOption(dispatch: Dispatch, branch: string) {
    try {
        SceneManager.selectBranch(branch); // MyActions are processed here. Side effects of MyActions may have happened.

        // These fire immediately because some MyActions may be asynchronous.
        if (SceneManager.sceneIsFinished) {
            dispatch(setMode(Mode.MainMenu));
        } else {
            dispatch(updateScene(SceneManager.dialogue, SceneManager.options));
        }
    } catch (error) {
        dispatch(setGameView(View.Error));
        dispatch(setError(error.stack || error.message));
    }
}

处理副作用的最佳方法是什么?如何最好地处理更改以反映在UI和状态中?需要明确的是,我的代码可以工作,但是我觉得我做错了方法。

0 个答案:

没有答案