Я пытаюсь сохранить определенное состояние редуктора в localStorage, чтобы оно не исчезало, даже если браузер обновляется.
Я написал некоторый код, но в хранилище я вижу только следующее:
"persist:root", "{"_persist":{\"version\":-1,\"rehydrated\":true}"}"
Нет user
данных. Что мне не хватает?
К вашему сведению, причина, по которой мне нужно хранить пользовательские данные как глобальную переменную, заключается в том, что мне приходится выполнять повторный рендеринг в зависимости от этого значения. Проблема в том, что при обновлении браузера он продолжает переход к странице входа в систему. Я проверил инструменты разработки Redux, пользовательские данные установлены правильно в компоненте Login
.
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;
Приложение.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();
🤔 А знаете ли вы, что...
С помощью JavaScript можно валидировать данные на стороне клиента, что улучшает пользовательский опыт.
Кажется, проблема связана с конфигурацией персистентности, в частности, с тем, что она вносит в белый список, и какую функцию редуктора она сохраняет:
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['user']
};
При этом сохраняется ключ user
редуктора, который вы сохраняете, например. user.reducer
, но у редуктора среза user
нет ключа user
для сохранения, это просто прямая user.reducer
функция.
const 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);
Либо сохраните всю функцию user.reducer
, например. нет белого списка в user.reducer
:
import { configureStore, createSlice } from '@reduxjs/toolkit';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import { persistStore } from 'redux-persist';
const user = createSlice({
name: 'user',
initialState: {
userId: 'anonymous',
isLoggedIn: false
},
reducers: {
changeUser(state, action) {
state.userId = action.payload.userId;
state.isLoggedIn = action.payload.isLoggedIn;
}
}
});
export const { changeUser } = user.actions;
const persistConfig = {
key: 'root',
storage: storage,
};
const persistedUserReducer = persistReducer(persistConfig, user.reducer);
const store = configureStore({
reducer: {
user: persistedUserReducer
}
})
export const persistor = persistStore(store);
export default store;
Или создайте функцию корневого редуктора, например. «combineReducers» и внесите в белый список состояние user
.
import {
configureStore,
createSlice,
combineReducers
} from '@reduxjs/toolkit';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import { persistStore } from 'redux-persist';
const user = createSlice({
name: 'user',
initialState: {
userId: 'anonymous',
isLoggedIn: false
},
reducers: {
changeUser(state, action) {
state.userId = action.payload.userId;
state.isLoggedIn = action.payload.isLoggedIn;
}
}
});
const persistConfig = {
key: 'root',
storage: storage,
whitelist: ['user']
};
export const { changeUser } = user.actions;
const rootReducer = combineReducers({
user: user.reducer,
});
const persistedRootReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedRootReducer,
})
export const persistor = persistStore(store);
export default store;