Reputation: 11
I've integrated into my Next.js app some of my own middleware into the Redux-Toolkit store using configureStore
. Middleware is designed to handle asynchronous actions such as fetchAccounts/fulfilled to update navigation state and user accounts. Despite adding them via
getDefaultMiddleware({
thunk: {
extraArgument: updateNavTabMiddleware, updateSelectedAccountMiddleware
},
serializableCheck: false,
}),
they seem to be greyed out. I used console.log
to debug incoming actions, but I don't see the expected logs. How to properly debug middleware in the Redux-Toolkit, and is there a way to ensure that they are actually executed in the expected order before the reducers?
In the documentation I read that the Redux-Toolkit configureStore
API automatically adds the Thunk middleware during store creation, so it should typically be available with no extra configuration needed.
Middleware
import { PayloadAction, Dispatch, MiddlewareAPI } from '@reduxjs/toolkit';
export const updateSelectedAccountMiddleware = (store: MiddlewareAPI) => (next: Dispatch) => (action: PayloadAction<Account[] | number>) => {
console.log(action);
if (action.type === 'accounts/fetchAccounts/fulfilled' && Array.isArray(action.payload)) {
const savedAccountId = getSelectedAccountIdLS();
const savedAccount = action.payload.find((account: Account) => account.id === Number(savedAccountId));
store.dispatch(setSelectedAccount(savedAccount || action.payload[0]));
}
if (action.type === 'accounts/deleteAccount/fulfilled' && typeof(action.payload) === 'number') {
const state = store.getState();
let newAccounts = state.accounts.data;
if (state.accounts.selected.id === action.payload) {
newAccounts = state.accounts.data.filter((item: Account) => item?.id !== action.payload);
}
saveSelectedAccountIdLS(newAccounts[0].id);
store.dispatch(setSelectedAccount(newAccounts[0]));
}
return next(action);
};
Store
export const makeStore = () => {
return configureStore({
reducer: {
visual: visualReducer,
user: userReducer,
accounts: accountsReducer,
topics: topicsReducer,
channelsHistoryRecords: channelsHistoryRecordsReducer,
competitors: competitorsReducer,
words: wordsReducer
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
thunk: {
extraArgument: updateNavTabMiddleware, updateSelectedAccountMiddleware
},
serializableCheck: false,
}),
})
}
// Infer the type of makeStore
export type AppStore = ReturnType<typeof makeStore>
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
export const useAppStore: () => AppStore = useStore
Upvotes: 1
Views: 314
Reputation: 202605
It appears you are only passing these middleware functions to the thunk middleware as its "extra argument". While it is true that Redux-Toolkit applies Thunk middleware by default, the Thunk middleware's extraArgument
doesn't add any additional middleware to the store. The extraArgument
is made available on createAsyncThunk
's thunkAPI
of the payloadCreator function.
If you are trying to add additional middlewares to your store then they should be appended/prepended to the middleware of the store when it's created.
See configureStore middleware and getDefaultMiddleware documentation for complete details.
Add your updateNavTabMiddleware
and updateSelectedAccountMiddleware
middleware functions to the store's middleware when creating/configuring it.
Store
const reducer = {
visual: visualReducer,
user: userReducer,
accounts: accountsReducer,
topics: topicsReducer,
channelsHistoryRecords: channelsHistoryRecordsReducer,
competitors: competitorsReducer,
words: wordsReducer
};
export const makeStore = () => {
return configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({ serializableCheck: false })
.concat(updateNavTabMiddleware, updateSelectedAccountMiddleware),
});
};
Upvotes: 1