Итак, я переношу свое приложение на NextJS, и у меня есть следующая конфигурация магазина. Сейчас это немного грязно, так как я буду все очищать/уменьшать дублированный код, как только все заработает.
import { configureStore } from '@reduxjs/toolkit';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist';
import expireReducer from 'redux-persist-expire';
import { API } from 'utils/RTKAPI';
import createSagaMiddleware from 'redux-saga';
import { createOrSyncSettings } from 'controllers/SettingsController';
import { syncWords } from 'controllers/WordController';
import { syncSentences } from 'controllers/SentenceController';
import { syncBookmarks } from 'controllers/BookmarkController';
import { syncReadArticles } from 'controllers/ReadArticleController';
import rootSaga from 'reducers/sagas/index';
import moment from 'moment';
import { createWrapper, HYDRATE } from 'next-redux-wrapper';
import rootReducer from 'reducers/rootReducer';
const makeStore = () => {
const SSR = typeof window === 'undefined';
if (SSR) {
const sagaMiddleware = createSagaMiddleware();
const store = configureStore({
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(
loggerMiddleware,
promiseMiddleware,
sagaMiddleware,
syncMiddleware,
API.middleware
),
reducer: rootReducer(),
});
sagaMiddleware.run(rootSaga);
return store;
} else {
const { persistStore, persistReducer } = require('redux-persist');
const sagaMiddleware = createSagaMiddleware();
const persistConfig = {
key: 'root',
storage: AsyncStorage,
blacklist: [API.reducerPath, 'router', 'sidebar', 'currentchar'],
transforms: [
expireReducer('date', {
expireSeconds: 86400,
expiredState: {
end_date: moment().format('YYYY-MM-DD'),
start_date: '2021-07-04',
},
autoExpire: true,
}),
],
};
const persistedReducer = persistReducer(persistConfig, rootReducer());
const store = configureStore({
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}).concat(
loggerMiddleware,
promiseMiddleware,
sagaMiddleware,
syncMiddleware,
API.middleware
),
reducer: persistedReducer,
});
sagaMiddleware.run(rootSaga);
store.__persistor = persistStore(store); // Necessary hack
return store;
}
};
export const wrapper = createWrapper(makeStore);
async function callSync(store) {
const storeState = await store.getState();
const profile = storeState.profile;
if (profile !== null) {
createOrSyncSettings(profile.id);
syncWords(profile);
syncSentences(profile);
syncBookmarks(profile);
syncReadArticles(profile);
}
}
const loggerMiddleware = (store) => (next) => (action) => {
next(action);
};
function promiseMiddleware({ dispatch }) {
function isPromise(val) {
return val && typeof val.then === 'function';
}
return (next) => (action) => {
return isPromise(action.payload)
? action.payload.then(
(result) => dispatch({ ...action, payload: result }),
(error) => dispatch({ ...action, payload: error, error: true })
)
: next(action);
};
}
const syncMiddleware = (store) => (next) => (action) => {
next(action);
if (action.type === 'persist/REHYDRATE') {
callSync(store);
}
};
Мой rootReducer тоже довольно стандартный:
export default () =>
combineReducers({
[API.reducerPath]: API.reducer,
categories,
profile,
...
Тем не менее, несмотря на мою конфигурацию, я продолжаю получать эту ошибку:
Error: Warning: Middleware for RTK-Query API at reducerPath "api" has not been added to the store.
You must add the middleware for RTK-Query to function correctly!
Что именно я делаю неправильно? Насколько я могу судить, мой reducerPath был добавлен в магазин.
Аналогичная конфигурация магазина отлично работала в предыдущей итерации моего приложения, в котором не использовался NextJS, поэтому мне интересно, что вызывает проблему сейчас.
Ваш рукописный Redux syncMiddleware
не работает. Он не возвращает результат next(action)
. Это означает, что если более позднее промежуточное ПО попытается вернуть значение, этот более поздний возвращаемый результат будет отброшен и никогда не будет возвращен из dispatch
.
Проверка конфигурации RTKQ основана на отправке специального действия, которое перехватывается промежуточным программным обеспечением RTKQ и возвращает соответствующий результат. Поскольку ваше промежуточное ПО отбрасывает этот результат, уровень пользовательского интерфейса делает вывод, что промежуточное ПО RTKQ на самом деле было добавлено неправильно. (И в каком-то смысле это было не так!)
Попытался добавить это в конец моего syncMiddleware: return next(action); Все еще вижу ту же ошибку
Похоже, у loggerMiddleware
та же проблема. Если вы убедитесь, что каждое промежуточное ПО обновлено, чтобы в какой-то момент вернуть результат next(action)
, это все еще происходит?
Да, похоже, проблема устранена. Странный. У меня было одно и то же промежуточное ПО на протяжении всей жизни моего приложения, и раньше оно никогда не вызывало эту проблему, только при переходе на Next. Я собираюсь прочитать документы о том, как написать лучшее промежуточное программное обеспечение. Спасибо.
Так что мне просто нужно вернуть следующее (действие), и все будет хорошо?