Redux和Thunk的通用模态

我一直在研究使用 React、Redux 和 Thunk 创建通用模态。理想情况下,我的状态如下所示:

export interface ConfirmModalState {
  isOpened: boolean;
  onConfirm: null | Function
}

export const initialConfirmModalState: ConfirmModalState = {
  isOpened: false,
  onConfirm: null
};

然而,这意味着将不可序列化的数据放入状态,这似乎是非常不鼓励的。

我已经阅读了markerikson 的一篇很棒的博文。但是,我认为提议的解决方案不适用于异步操作和 Thunk。

你建议如何解决这个问题?

回答

我实际上写了你链接的帖子,几年后我写了那个帖子的扩展版本:

实用 Redux,第 10 部分:管理模式和上下文菜单。

自从我写那篇文章以来,我自己实际上已经实现了这种方法的几种变体,我发现的最佳解决方案是添加一个自定义中间件,当您发送“显示模式”操作时返回一个承诺,并解决承诺对话框关闭时带有“返回值”。

在https://github.com/AKolodeev/redux-promising-modals 上有这种方法的现有实现。我最终做出了自己的实现。我在https://gist.github.com/markerikson/8cd881db21a7d2a2011de9e317007580的要点中有一个我自己开发的方法的部分版本,中间件大致如下:

export const dialogPromiseMiddleware: Middleware<DialogPromiseDispatch> = storeAPI => {
    const dialogPromiseResolvers: Record<string, Resolver> = {};

    return next => (action: AnyAction) => {
        switch (action.type) {
            // Had to resort to `toString()` here due to https://github.com/reduxjs/redux-starter-kit/issues/157
            case showDialogInternal.toString(): {
                next(action);
                let promiseResolve: Resolver;
                const dialogPromise = new Promise((resolve: Resolver) => {
                    promiseResolve = resolve;
                });

                dialogPromiseResolvers[action.payload.id] = promiseResolve!;

                return dialogPromise;
            }
            case closeDialog.toString(): {
                next(action);
                const {id, values} = action.payload;
                const resolver = dialogPromiseResolvers[id];
                if (resolver) {
                    resolver(values);
                }

                delete dialogPromiseResolvers[id];
                break;
            }
            default:
                return next(action);
        }
    };
};

(注意:当我遇到一些 TS 语法问题以使其正常工作时,我提出了这个要点,所以很可能它不会 100% 开箱即用。RTK 现在还包括一些 .match()在这里有用的动作匹配实用程序。但是,它显示了基本方法。)

在一个组件中的粗略用法是:

const closedPromise = dispatch(showDialog("TestDialog", {dialogNumber : counter});
const result = await closedPromise
// do something with the result

这样您就可以在要求首先显示对话框的地方编写“确认时”逻辑。


以上是Redux和Thunk的通用模态的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>