我已经在我的 React 应用程序中设置了 Redux Toolkit,但最终遇到了一个问题。我有一个包含多个中间件的 middleware.js 文件,还有一个包含商店配置的 store.js 文件。我需要立即导出 middleware.js 中的所有中间件,这样我就可以将其连接到 store.js 中,而无需多个 concat(或单个 concat 中的大数组)。我创建了以下示例,我认为它可以工作。 问题出在
toastMiddleware
函数上。看起来这个中间件运行了两次。 console.log()
仅运行一次,但它会同时添加两条 Toast 消息。当我在商店中分别连接两个中间件函数时,不会发生此问题。所以我不确定我是否正确创建了这个组合中间件。有什么帮助吗?
中间件.js
import { addError } from "../error.slice";
import { addToast } from "../toast.slice ";
const apiErrorMiddleware = (api) => (next) => (action) => {
if (action.type.endsWith('/rejected') && action.payload && action?.payload?.status != 401) {
api.dispatch(addError({ response: action.payload, meta: action.meta, arg: action.error }));
}
return next(action);
};
const toastMiddleware = (api) => (next) => (action) => {
const mutationVerb = action?.payload?.created?.length ? 'Created' : action?.payload?.updated?.length ? 'Updated' : action?.payload?.upserted?.length ? 'Upserted' : null;
if (action.type.endsWith('executeMutation/fulfilled')) {
console.log('toast mid', action)
if (mutationVerb)
api.dispatch(addToast({title: mutationVerb, content: 'Operation completed successfully.', variant: 'success'}));
else
api.dispatch(addToast({title: 'No Change', content: 'Operation completed successfully.', variant: 'info'}));
}
return next(action);
};
export const combinedMiddleware = (api) => (next) => (action) => [
apiErrorMiddleware(api)(next)(action),
toastMiddleware(api)(next)(action),
];
store.js
import { configureStore } from '@reduxjs/toolkit';
import api from './api.slice';
import errorSlice from './error.slice';
import { combinedMiddleware } from './middleware/apiMiddleware';
import toastSlice from './toast.slice ';
export const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
errorSlice: errorSlice,
toastSlice: toastSlice,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false })
.concat([api.middleware, combinedMiddleware])
});
我不太明白正常将中间件添加到商店的问题或反对是什么,但如果您只是想在其他地方定义一个中间件数组以添加到商店,那么我建议简化代码只是这样,而不是创建调用其他中间件函数的自定义中间件函数。通常,中间件是一个简单的函数列表,每个函数都完成自己的工作,然后调用“链”中的下一个中间件并返回结果。
示例:
export const middleware = [
apiErrorMiddleware,
toastMiddleware,
];
将这些传播到
concat
方法中:
import { configureStore } from '@reduxjs/toolkit';
import api from './api.slice';
import errorSlice from './error.slice';
import { middleware } from './middleware/middleware';
import toastSlice from './toast.slice ';
export const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
errorSlice: errorSlice,
toastSlice: toastSlice,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false })
.concat([api.middleware, ...middleware]),
});