感谢markerikson 提供答案。这启发了我创建一个带有 thunk 的解决方案。请在这里给我一些反馈:)
我将在我的示例中使用 hooks 和 @reduxjs/toolkit。
这是我的ConfirmationModalreducer 的状态:
export interface confirmationModalState {
isOpened: boolean;
isConfirmed: boolean;
isCancelled: boolean;
}
export const initialConfirmationModalState: confirmationModalState = {
isOpened: false,
isConfirmed: false,
isCancelled: false,
};
这是切片(reducer 和动作的组合):
import { createSlice } from '@reduxjs/toolkit';
import { initialConfirmationModalState } from './state';
const confirmationModalSlice = createSlice({
name: 'controls/confirmationModal',
initialState: initialConfirmationModalState,
reducers: {
open: state => {
state.isOpened = true;
state.isConfirmed = false;
state.isCancelled = false;
},
confirm: state => {
state.isConfirmed = true;
state.isOpened = false;
},
cancel: state => {
state.isCancelled = true;
state.isOpened = false;
},
},
});
export const confirmationModalActions = confirmationModalSlice.actions;
export default confirmationModalSlice;
这是它的 thunk 动作:
import { createAsyncThunk } from '@reduxjs/toolkit';
import ThunkApiConfig from '../../../types/ThunkApiConfig';
import { AppState } from '../../reducers';
import { confirmationModalActions } from './slice';
const confirmationModalThunkActions = {
open: createAsyncThunk<boolean, void, ThunkApiConfig>(
'controls/confirmationModal',
async (_, { extra, dispatch }) => {
const store = extra.store;
dispatch(confirmationModalActions.open());
return await new Promise<boolean>(resolve => {
store.subscribe(() => {
const state: AppState = store.getState();
if (state.controls.confirmationModal.isConfirmed) {
resolve(true);
}
if (state.controls.confirmationModal.isCancelled) {
resolve(false);
}
});
});
},
),
};
export default confirmationModalThunkActions;
您会注意到它使用extra.store 来执行subscribe。我们需要在创建商店时提供:
import combinedReducers from './reducers';
import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { ThunkExtraArguments } from '../types/ThunkExtraArguments';
function createStore() {
const thunkExtraArguments = {} as ThunkExtraArguments;
const customizedMiddleware = getDefaultMiddleware({
thunk: {
extraArgument: thunkExtraArguments,
},
});
const store = configureStore({
reducer: combinedReducers,
middleware: customizedMiddleware,
});
thunkExtraArguments.store = store;
return store;
}
export default createStore();
现在,让我们创建一个钩子,允许我们调度上述所有操作:
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from '../../../reducers';
import { useCallback } from 'react';
import confirmationModalThunkActions from '../thunk';
import { confirmationModalActions } from '../slice';
import { AppDispatch } from '../../../../index';
export function useConfirmationModalState() {
const dispatch: AppDispatch = useDispatch();
const { isOpened } = useSelector((state: AppState) => ({
isOpened: state.controls.confirmationModal.isOpened,
}));
const open = useCallback(() => {
return dispatch(confirmationModalThunkActions.open());
}, [dispatch]);
const confirm = useCallback(() => {
dispatch(confirmationModalActions.confirm());
}, [dispatch]);
const cancel = useCallback(() => {
dispatch(confirmationModalActions.cancel());
}, [dispatch]);
return {
open,
confirm,
cancel,
isOpened,
};
}
(不要忘记将confirm 和cancel 附加到您的模态按钮中)
就是这样!我们现在可以发送我们的确认模式:
export function usePostControls() {
const { deleteCurrentPost } = usePostsManagement();
const { open } = useConfirmationModalState();
const handleDelete = async () => {
const { payload: isConfirmed } = await open();
if (isConfirmed) {
deleteCurrentPost();
}
};
return {
handleDelete,
};
}