React Redux Persist 正在补水,但不会检索存储的数据,而是默认 [英] React Redux Persist is rehydrating, but no stored data is retrieved, instead, default

查看:42
本文介绍了React Redux Persist 正在补水,但不会检索存储的数据,而是默认的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经被这个问题困扰了两天,所以我需要帮助!

I've been struggling with this problem for two days, so I need help!

我有一个 React 网站,我在其中添加了 Redux Persist(还有用于处理请求的 Redux Saga),如文档所述.

I have a React web in wich i've added Redux Persist (also Redux Saga for handling requests) as the documentation said.

我正在测试一个中间没有任何传奇的商店,当我触发一个动作时,数据会更新,我可以在调试器中看到它,但是当我刷新时,尽管有 Redux Hydrate 过程运行,该值将恢复为默认值.

I'm testing with a store that doesn't have any saga in the middle, when I trigger an action, the data is updated, I can see it in the Debugger, but when i refresh, despite the Redux Hydrate process runs, that value goes back to the default one.

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

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(我正在测试的那个,布局)

reducer.js (the one i'm testing, Layout)

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)

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();

和类的片段

...
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));

调试器

第一次运行,当我切换菜单栏以触发动作时)

First time run, when i toggle the menu bar so the action gets triggered)

刷新浏览器后,rehydration 应该将 layout -> is_toggle 设置为 false.. 但它仍然是 true(默认)

After refreshing the browser, the rehydrate should bring the layout -> is_toggle to false.. but it remains true (as default)

彩色片段

推荐答案

我认为您的问题在于您如何设置store:

I think your issue is how you are setting up your store:

const store = createStore(persistedReducer, composeEnhancers(applyMiddleware(sagaMiddleware)));

这个函数的结构是createStore(reducer, [preloadedState], [enhancer])

所以你试图将你的 enhancers 作为 preloadedState 传递.

So you are trying to pass your enhancers as preloadedState.

尝试将其更改为:

const store = createStore(persistedReducer, {}, composeEnhancers(applyMiddleware(sagaMiddleware)));

此外,当您设置 persistConfig 时,我看到您已注释掉白名单.您想要保留的任何减速器状态都需要在此列表中,因此不应将其注释掉:

Also, when you setup your persistConfig I see that you have the whitelist commented out. Any reducer state you want to keep needs to be in this list so it should not be commented out:

// whitelist: ['login', 'account', 'layout'],  // uncomment this

最后作为旁注,您不需要在所有 switch case 中使用 break

And finally as a side note, you don't need break in all of your switch cases

这篇关于React Redux Persist 正在补水,但不会检索存储的数据,而是默认的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆