redux-persist
redux-persist copied to clipboard
Redux persist is not working when redux dev tool is disabled.
In my app, redux persist was not working in production. But, everything was working fine on development environment. Turns out it only works when redux dev tool is enabled, which was disabled in production mode. Is it supposed to be like this? I am using these packages in my next.js app:
"@reduxjs/toolkit": "^1.5.0",
"react-redux": "^7.2.2",
"redux-persist": "^6.0.0",
"next": "10.0.3",
Here is my code:
import { combineReducers, configureStore, ThunkAction, Action } from '@reduxjs/toolkit';
import reducerRegistry from 'redux/reduxRegistry';
import { useDispatch } from 'react-redux';
import login from 'features/login/login.slice';
import notification from 'features/notification/notification.slice';
import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, PURGE, REGISTER, REHYDRATE } from 'redux-persist';
import createWebStorage from 'redux-persist/lib/storage/createWebStorage';
const createNoopStorage = () => {
return {
getItem(_key) {
return Promise.resolve(null);
},
setItem(_key, value) {
return Promise.resolve(value);
},
removeItem(_key) {
return Promise.resolve();
},
};
};
const storage = typeof window !== 'undefined' ? createWebStorage('local') : createNoopStorage();
const isProduction = process.env.NODE_ENV === 'production';
const combine = (asyncReducers = {}) => {
return combineReducers({
auth: login,
notification,
...asyncReducers,
});
};
const persistConfig = {
key: 'root',
storage,
whitelist: ['auth', 'register'],
};
const persistedReducer = persistReducer(persistConfig, combine());
const getMiddlewares = (getDefaultMiddleware) => {
const defaultMiddlewares = getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
});
if (isProduction) {
return defaultMiddlewares;
// eslint-disable-next-line @typescript-eslint/no-var-requires,global-require
// const { logger } = require('./_fake/logger');
// return defaultMiddlewares.concat(logger);
}
// eslint-disable-next-line @typescript-eslint/no-var-requires,global-require
const { logger } = require('redux-logger');
return defaultMiddlewares.concat(logger);
};
export const store = configureStore({
reducer: persistedReducer,
middleware: getMiddlewares,
devTools: false, // It works fine if I set this to true
});
reducerRegistry.setChangeListener((reducers) => {
store.replaceReducer(persistReducer(persistConfig, combine(reducers)));
});
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>;
// @ts-ignore
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const dispatcher = store.dispatch as ReturnType<typeof useAppDispatch>;
Yeah, I found this issue too.
After review, I realized that I am using redux-injectors to combine the reducers dynamically. Thus I have to set the option: manualPersist: true and manually dispatch the persist event later.
@mutoo do you call persistor.persist or do you use store.dispatch to call the persist method? Please share your solution for this
@mutoo do you call
persistor.persistor do you use store.dispatch to call the persist method? Please share your solution for this
hi @smac89 here is the code related to my issue
the persistor with manualPersist disabled:
https://github.com/mutoo/critterpedia-plus/blob/d0be98768a6bc87ff01e006cceaa57092c9730ab/app/configureStore.js#L65
export const persistor = persistStore(store, { manualPersist: false });
the component that injects persistReducer and manually dispatches persist with persistor: https://github.com/mutoo/critterpedia-plus/blob/d0be98768a6bc87ff01e006cceaa57092c9730ab/app/pages/Critterpedia/index.js#L46
useInjectReducer({ key, reducer });
useEffect(() => {
persistor.persist();
}, []);
I hope this will help you.
Hi there! Same issue here. Any solutions? Not using redux-injectors