I'm trying to persist specific reducer state to localStorage so that it wouldn't be disappear even though the browser is refreshed.
I've written some code, but in the storage all I can see is just like this:
"persist:root", "{"_persist":{\"version\":-1,\"rehydrated\":true}"}"
Tthere's no user data. What am I missing?
FYI, the reason why I need to store user data as global variable is that I have to re-render depending on this value. The problem is that when the browser is refreshed, it keeps navigating to loginPage. I've checked redux dev tools, the user data is set properly in the Login component.
store.js
import { configureStore, createSlice } from '@reduxjs/toolkit'
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import { persistStore } from 'redux-persist';
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['user']
};
let user = createSlice({
name: 'user',
initialState: {
userId: 'anonymous',
isLoggedIn: false
},
reducers: {
changeUser(state, action) {
state.userId = action.payload.userId;
state.isLoggedIn = action.payload.isLoggedIn;
}
}
})
const persistedReducer = persistReducer(persistConfig, user.reducer);
export let { changeUser } = user.actions;
let store = configureStore({
reducer: {
user: persistedReducer
}
// persistedReducer
})
export const persistor = persistStore(store);
export default store;
App.js
function App(){
const isLoggedIn = useSelector((state) => state.user.isLoggedIn);
return (
<BrowserRouter>
<RedirectToLogin />
<Center>
{isLoggedIn && <Sidebar userRole={''} />}
<Routes>
<Route path="/loginPage" element={<Login />} />
{isLoggedIn ? (
<>
<Route element={<ProtectedRoute isLoggedIn={isLoggedIn} />} />
<Route path="/" element={<Editor/>}/>
<Route path={"/loginPage"} element={<Login/>}/>
<Route path="*" element={<NotFoundPage/>}/>
</>
) : (
<>
<Route path="*" element={<Navigate to="/loginPage" replace />} />
</>
)}
</Routes>
</Center>
</BrowserRouter>
)
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store, {persistor} from "./store";
import {Provider} from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
</React.StrictMode>
);
reportWebVitals();
Issue
The issue it seems is with the persistence configuration, specifically what it whitelists, and what reducer function it is persiting:
This persists the
userkey of the reducer you are persisting, e.g.user.reducer, but theuserslice's reducer doesn't have anyuserkey to persist, it's just the directuser.reducerfunction.Solution
Either persist the entire
user.reducerfunction, e.g. no whitelisting in theuser.reducer:Or create a root reducer function, e.g. "combineReducers", and whitelist the
userstate.