React Redux Persist 正在重新水化,但没有检索存储的数据,而是默认
React Redux Persist is rehydrating, but no stored data is retrieved, instead, default
我已经为这个问题苦苦挣扎了两天,所以我需要帮助!
我有一个 React 网络,我在其中添加了 Redux Persist(还有用于处理请求的 Redux Saga),如文档所述。
我正在测试中间没有任何传奇的商店,当我触发一个动作时,数据会更新,我可以在调试器中看到它,但是当我刷新时,尽管 Redux Hydrate 进程 运行s,该值恢复为默认值。
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga'
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import rootReducer from './reducers';
// import rootSaga from './sagas';
const persistConfig = {
key: 'root',
storage: storage,
// whitelist: ['login', 'account', 'layout'],
stateReconciler: autoMergeLevel2, // see "Merge Process" section for details.
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(sagaMiddleware)));
const persistor = persistStore(store);
export { store, persistor, sagaMiddleware };
reducers.js
import { combineReducers } from 'redux';
// Front
import layout from './layout/reducer';
// Authentication Module
import account from './auth/register/reducer';
import login from './auth/login/reducer';
import forget from './auth/forgetpwd/reducer';
const rootReducer = combineReducers({
layout,
account,
login,
forget
});
export default rootReducer;
reducer.js(我正在测试的布局)
import { ACTIVATE_AUTH_LAYOUT, ACTIVATE_NON_AUTH_LAYOUT, TOGGLE, TOGGLE_LD } from './actionTypes';
const initialState={
topbar:true,
sidebar:true,
footer:true,
is_toggle : true,
is_light : true
}
const layout = (state=initialState,action) => {
switch(action.type){
case ACTIVATE_AUTH_LAYOUT:
state = {
...state,
...action.payload
}
break;
case ACTIVATE_NON_AUTH_LAYOUT:
state = {
...state,
...action.payload
}
break;
case TOGGLE:
state = {
...state,
is_toggle : action.payload
}
break;
case TOGGLE_LD:
state = {
...state,
is_light : action.payload
}
break;
default:
// state = state;
break;
}
return state;
}
export default layout;
actions.js
import { ACTIVATE_AUTH_LAYOUT, ACTIVATE_NON_AUTH_LAYOUT, TOGGLE, TOGGLE_LD } from './actionTypes';
export const activateAuthLayout = () => {
return {
type: ACTIVATE_AUTH_LAYOUT,
payload: {
topbar: true,
sidebar: true,
footer: true,
rodri: 'butta',
layoutType: 'Auth'
}
}
}
export const activateNonAuthLayout = () => {
return {
type: ACTIVATE_NON_AUTH_LAYOUT,
payload: {
topbar: false,
sidebar: false,
footer: false,
layoutType: 'NonAuth'
}
}
}
export const toggleSidebar = (is_toggle) => {
return {
type: TOGGLE,
payload: is_toggle
}
}
export const toggleLightDark = (is_light) => {
return {
type: TOGGLE_LD,
payload: is_light
}
}
index.js(APP)
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/lib/integration/react';
import rootSaga from './store/sagas';
import {persistor, store, sagaMiddleware} from './store';
sagaMiddleware.run(rootSaga);
const app = (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>
);
ReactDOM.render(app, document.getElementById('root'));
serviceWorker.unregister();
和片段class
...
this.props.toggleSidebar(!this.props.is_toggle);
...
const mapStatetoProps = state => {
const { is_toggle,is_light } = state.layout;
return { is_toggle,is_light };
}
export default withRouter(connect(mapStatetoProps, { toggleSidebar })(Topbar));
调试器
第一次 运行,当我切换菜单栏时触发操作)
刷新浏览器后,rehydrate 应使布局 -> is_toggle 变为 false..但它仍然是 true(默认)
彩色片段:
我认为你的问题是你如何设置 store
:
const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(sagaMiddleware)));
这个函数的结构是createStore(reducer, [preloadedState], [enhancer])
所以您正试图将 enhancers
作为 preloadedState
传递。
尝试将其更改为:
const store = createStore(persistedReducer, {}, composeEnhancers(applyMiddleware(sagaMiddleware)));
此外,当您设置 persistConfig
时,我看到您已将白名单注释掉。您要保留的任何减速器状态都需要在此列表中,因此不应将其注释掉:
// whitelist: ['login', 'account', 'layout'], // uncomment this
最后作为旁注,您不需要 break
在所有 switch cases
我遇到了同样的错误,对我有用的是作者问题的评论说:
And this solution didn't worked for me :( https://github.com/rt2zz/redux-persist/issues/1114#issuecomment-549107922
因此,如果有人卡在这个问题上,那么可以在以下位置尝试此解决方案:https://github.com/rt2zz/redux-persist/issues/1114#issuecomment-549107922
问题:我的 Persist 在 rehydrate 之前先被调用,使我的状态再次变为默认状态。因此,每次我刷新时,我的状态都从本地存储中消失了。
我已经为这个问题苦苦挣扎了两天,所以我需要帮助!
我有一个 React 网络,我在其中添加了 Redux Persist(还有用于处理请求的 Redux Saga),如文档所述。
我正在测试中间没有任何传奇的商店,当我触发一个动作时,数据会更新,我可以在调试器中看到它,但是当我刷新时,尽管 Redux Hydrate 进程 运行s,该值恢复为默认值。
store.js
import { createStore, applyMiddleware, compose } from 'redux';
import createSagaMiddleware from 'redux-saga'
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import rootReducer from './reducers';
// import rootSaga from './sagas';
const persistConfig = {
key: 'root',
storage: storage,
// whitelist: ['login', 'account', 'layout'],
stateReconciler: autoMergeLevel2, // see "Merge Process" section for details.
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(sagaMiddleware)));
const persistor = persistStore(store);
export { store, persistor, sagaMiddleware };
reducers.js
import { combineReducers } from 'redux';
// Front
import layout from './layout/reducer';
// Authentication Module
import account from './auth/register/reducer';
import login from './auth/login/reducer';
import forget from './auth/forgetpwd/reducer';
const rootReducer = combineReducers({
layout,
account,
login,
forget
});
export default rootReducer;
reducer.js(我正在测试的布局)
import { ACTIVATE_AUTH_LAYOUT, ACTIVATE_NON_AUTH_LAYOUT, TOGGLE, TOGGLE_LD } from './actionTypes';
const initialState={
topbar:true,
sidebar:true,
footer:true,
is_toggle : true,
is_light : true
}
const layout = (state=initialState,action) => {
switch(action.type){
case ACTIVATE_AUTH_LAYOUT:
state = {
...state,
...action.payload
}
break;
case ACTIVATE_NON_AUTH_LAYOUT:
state = {
...state,
...action.payload
}
break;
case TOGGLE:
state = {
...state,
is_toggle : action.payload
}
break;
case TOGGLE_LD:
state = {
...state,
is_light : action.payload
}
break;
default:
// state = state;
break;
}
return state;
}
export default layout;
actions.js
import { ACTIVATE_AUTH_LAYOUT, ACTIVATE_NON_AUTH_LAYOUT, TOGGLE, TOGGLE_LD } from './actionTypes';
export const activateAuthLayout = () => {
return {
type: ACTIVATE_AUTH_LAYOUT,
payload: {
topbar: true,
sidebar: true,
footer: true,
rodri: 'butta',
layoutType: 'Auth'
}
}
}
export const activateNonAuthLayout = () => {
return {
type: ACTIVATE_NON_AUTH_LAYOUT,
payload: {
topbar: false,
sidebar: false,
footer: false,
layoutType: 'NonAuth'
}
}
}
export const toggleSidebar = (is_toggle) => {
return {
type: TOGGLE,
payload: is_toggle
}
}
export const toggleLightDark = (is_light) => {
return {
type: TOGGLE_LD,
payload: is_light
}
}
index.js(APP)
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/lib/integration/react';
import rootSaga from './store/sagas';
import {persistor, store, sagaMiddleware} from './store';
sagaMiddleware.run(rootSaga);
const app = (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>
);
ReactDOM.render(app, document.getElementById('root'));
serviceWorker.unregister();
和片段class
...
this.props.toggleSidebar(!this.props.is_toggle);
...
const mapStatetoProps = state => {
const { is_toggle,is_light } = state.layout;
return { is_toggle,is_light };
}
export default withRouter(connect(mapStatetoProps, { toggleSidebar })(Topbar));
调试器
第一次 运行,当我切换菜单栏时触发操作)
刷新浏览器后,rehydrate 应使布局 -> is_toggle 变为 false..但它仍然是 true(默认)
彩色片段:
我认为你的问题是你如何设置 store
:
const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(sagaMiddleware)));
这个函数的结构是createStore(reducer, [preloadedState], [enhancer])
所以您正试图将 enhancers
作为 preloadedState
传递。
尝试将其更改为:
const store = createStore(persistedReducer, {}, composeEnhancers(applyMiddleware(sagaMiddleware)));
此外,当您设置 persistConfig
时,我看到您已将白名单注释掉。您要保留的任何减速器状态都需要在此列表中,因此不应将其注释掉:
// whitelist: ['login', 'account', 'layout'], // uncomment this
最后作为旁注,您不需要 break
在所有 switch cases
我遇到了同样的错误,对我有用的是作者问题的评论说:
And this solution didn't worked for me :( https://github.com/rt2zz/redux-persist/issues/1114#issuecomment-549107922
因此,如果有人卡在这个问题上,那么可以在以下位置尝试此解决方案:https://github.com/rt2zz/redux-persist/issues/1114#issuecomment-549107922
问题:我的 Persist 在 rehydrate 之前先被调用,使我的状态再次变为默认状态。因此,每次我刷新时,我的状态都从本地存储中消失了。