Redux Persist not persisting state with async reducers

Viewed 344

Redux persist is not working. Persist does not persist anything. I have tried all solutions but still not working. The app works fine but redux persists not working. I am also using async injected reducers. Anyone can help. Thanks

This is the App.js file :

import FuseAuthorization from '@fuse/core/FuseAuthorization';
import FuseLayout from '@fuse/core/FuseLayout';
import FuseTheme from '@fuse/core/FuseTheme';
import history from '@history';
import { createGenerateClassName, jssPreset, StylesProvider } from '@material-ui/core/styles';
import { MuiPickersUtilsProvider } from '@material-ui/pickers';
import { create } from 'jss';
import jssExtend from 'jss-plugin-extend';
import rtl from 'jss-rtl';
import Provider from 'react-redux/es/components/Provider';
import { Router } from 'react-router-dom';
import { SnackbarProvider } from 'notistack';
import DateFnsUtils from '@date-io/date-fns';
import AppContext from './AppContext';
import { Auth } from './auth';
import routes from './fuse-configs/routesConfig';
import {store persistor} from './store';
import { PersistGate } from 'redux-persist/integration/react';
import { persistStore } from 'redux-persist';
const jss = create({
    ...jssPreset(),
    plugins: [...jssPreset().plugins, jssExtend(), rtl()],
    insertionPoint: document.getElementById('jss-insertion-point')
});

const generateClassName = createGenerateClassName({ disableGlobal: true });
const App = () => {
    return (
        <AppContext.Provider
            value={{
                routes
            }}
        >
            <StylesProvider jss={jss} generateClassName={generateClassName}>
                <Provider store={store}>
                    <PersistGate persistor={persistor}>
                        <MuiPickersUtilsProvider utils={DateFnsUtils}>
                            <Auth>
                                <Router history={history}>
                                    <FuseAuthorization>
                                        <FuseTheme>
                                            <SnackbarProvider
                                                maxSnack={5}
                                                anchorOrigin={{
                                                    vertical: 'bottom',
                                                    horizontal: 'right'
                                                }}
                                                classes={{
                                                    containerRoot: 'bottom-0 right-0 mb-52 md:mb-68 mr-8 lg:mr-80 z-99'
                                                }}
                                            >
                                                <FuseLayout />
                                            </SnackbarProvider>
                                        </FuseTheme>
                                    </FuseAuthorization>
                                </Router>
                            </Auth>
                        </MuiPickersUtilsProvider>
                    </PersistGate>
                </Provider>
            </StylesProvider>
        </AppContext.Provider>
    );
};

This is where the store is created:

import { configureStore } from '@reduxjs/toolkit';
import createReducer from './rootReducer';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
if (process.env.NODE_ENV === 'development' && module.hot) {
    module.hot.accept('./rootReducer', () => {
        const newRootReducer = require('./rootReducer').default;
        store.replaceReducer(newRootReducer.createReducer());
    });
}

const middlewares = [];

if (process.env.NODE_ENV === 'development') {
    const { createLogger } = require(`redux-logger`);
    const logger = createLogger({ collapsed: (getState, action, logEntry) => !logEntry.error });

    middlewares.push(logger);
}
const persistConfig = {
    key: 'root',
    storage
};
const persistedReducer = persistReducer(persistConfig, createReducer());
export const store = configureStore({
    reducer: persistedReducer,
    middleware: getDefaultMiddleware =>
        getDefaultMiddleware({
            immutableCheck: false,
            serializableCheck: false
        }).concat(middlewares),
    devTools: process.env.NODE_ENV === 'development'
});

store.asyncReducers = {};

export const injectReducer = (key, reducer) => {
    if (store.asyncReducers[key]) {
        return false;
    }
    store.asyncReducers[key] = reducer;
    store.replaceReducer(createReducer(store.asyncReducers));
    return store;
};
export const persistor = persistStore(store);

This is the createReducer():

import { combineReducers } from '@reduxjs/toolkit';
import auth from 'app/auth/store';
import fuse from './fuse';
import i18n from './i18nSlice';

const createReducer = asyncReducers => (state, action) => {
    const combinedReducer = combineReducers({
        auth,
        fuse,
        i18n,
        ...asyncReducers
    });

    /*
    Reset the redux store when the user logged out
     */
    if (action.type === 'auth/user/userLoggedOut') {
        state = undefined;
    }

    return combinedReducer(state, action);
};

export default createReducer;
1 Answers

You should replace the store.replaceReducer inside your injectReducer function with the new persisted reducer.

Replace this line:

store.replaceReducer(createReducer(store.asyncReducers));

with this:

store.replaceReducer(persistReducer(persistConfig, createReducer(store.asyncReducers)));
Related