2017-12-01 12 views
0

redux-session 라이브러리를 사용하여 페이지 새로 고침을 통해 내 앱 상태를 저장하려고하지만 작동하지 않습니다.세션이 페이지 새로 고침을 통해 복원되지 않음 - 끊임없이 중첩 된 개체

내가 세션 개체에서 보았다 그것은 즉, 자신을 중첩 끊임없이 데이터를 가져 오는, 그러나 아주 천천히 채우고있다 :

session: { myobject: {}, session: { myobject: {data:2}, session: { myobject: {data:2}, session: {...

세션이 올바른 것 같다

selectState (state) { 
     return { 
      user: state.toJS().session.myobject 
     }; 
    } 

를 추가 (로컬 저장소의 세션은 {myobject : {data : 2}}), 페이지를 다시로드하면 덮어 쓰기 전에 세션이 복구되지 않은 것처럼 보입니다. 도서관의 실례가 아니거나 온라인상의 질문이없는 것 같습니다.

/** 
* app.js 
* 
* This is the entry file for the application, only setup and boilerplate 
* code. 
*/ 

// Needed for redux-saga es6 generator support 
import 'babel-polyfill'; 

// Import all the third party stuff 
import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 
import { ConnectedRouter } from 'react-router-redux'; 
import FontFaceObserver from 'fontfaceobserver'; 
import createHistory from 'history/createBrowserHistory'; 
import { createSession } from 'redux-session'; 
import 'sanitize.css/sanitize.css'; 

// Import root app 
import App from 'containers/App'; 

// Import Language Provider 
import LanguageProvider from 'containers/LanguageProvider'; 

// Load the favicon, the manifest.json file and the .htaccess file 
/* eslint-disable import/no-webpack-loader-syntax */ 
import '!file-loader?name=[name].[ext]!./images/favicon.ico'; 
import '!file-loader?name=[name].[ext]!./images/icon-72x72.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-96x96.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-120x120.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-128x128.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-144x144.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-152x152.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-167x167.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-180x180.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-192x192.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-384x384.png'; 
import '!file-loader?name=[name].[ext]!./images/icon-512x512.png'; 
import '!file-loader?name=[name].[ext]!./manifest.json'; 
import 'file-loader?name=[name].[ext]!./.htaccess'; // eslint-disable-line import/extensions 
/* eslint-enable import/no-webpack-loader-syntax */ 

import configureStore from './configureStore'; 

// Import i18n messages 
import { translationMessages } from './i18n'; 

// Import CSS reset and Global Styles 
import './global-styles'; 

// Observe loading of Open Sans (to remove open sans, remove the <link> tag in 
// the index.html file and this observer) 
const openSansObserver = new FontFaceObserver('Open Sans', {}); 

// When Open Sans is loaded, add a font-family using Open Sans to the body 
openSansObserver.load().then(() => { 
    document.body.classList.add('fontLoaded'); 
},() => { 
    document.body.classList.remove('fontLoaded'); 
}); 

// Create redux store with history 
const initialState = {}; 
const history = createHistory(); 
const session = createSession({ 
    ns: 'dbwy1642b7c9e02q', 
}); 

const store = configureStore(initialState, history, session); 
const MOUNT_NODE = document.getElementById('app'); 

const render = (messages) => { 
    ReactDOM.render(
    <Provider store={store}> 
     <LanguageProvider messages={messages}> 
     <ConnectedRouter history={history}> 
      <App /> 
     </ConnectedRouter> 
     </LanguageProvider> 
    </Provider>, 
    MOUNT_NODE 
); 
}; 

if (module.hot) { 
    // Hot reloadable React components and translation json files 
    // modules.hot.accept does not accept dynamic dependencies, 
    // have to be constants at compile-time 
    module.hot.accept(['./i18n', 'containers/App'],() => { 
    ReactDOM.unmountComponentAtNode(MOUNT_NODE); 
    render(translationMessages); 
    }); 
} 

// Chunked polyfill for browsers without Intl support 
if (!window.Intl) { 
    (new Promise((resolve) => { 
    resolve(import('intl')); 
    })) 
    .then(() => Promise.all([ 
     import('intl/locale-data/jsonp/en.js'), 
     import('intl/locale-data/jsonp/de.js'), 
    ])) 
    .then(() => render(translationMessages)) 
    .catch((err) => { 
     throw err; 
    }); 
} else { 
    render(translationMessages); 
} 

// Install ServiceWorker and AppCache in the end since 
// it's not most important operation and if main code fails, 
// we do not want it installed 
if (process.env.NODE_ENV === 'production') { 
    require('offline-plugin/runtime').install(); // eslint-disable-line global-require 
} 

configureStore.js :

/** 
* Create the store with dynamic reducers 
*/ 

import { createStore, applyMiddleware, compose } from 'redux'; 
import { fromJS } from 'immutable'; 
import { routerMiddleware } from 'react-router-redux'; 
import thunkMiddleware from 'redux-thunk'; 
import createSagaMiddleware from 'redux-saga'; 
import createReducer from './reducers'; 

const sagaMiddleware = createSagaMiddleware(); 

export default function configureStore(initialState = {}, history, session) { 
    // Create the store with two middlewares 
    // 1. sagaMiddleware: Makes redux-sagas work 
    // 2. routerMiddleware: Syncs the location/URL path to the state 
    const middlewares = [ 
     session, 
    sagaMiddleware, 
    routerMiddleware(history), 
     thunkMiddleware 
    ]; 

    const enhancers = [ 
    applyMiddleware(...middlewares), 
    ]; 

    // If Redux DevTools Extension is installed use it, otherwise use Redux compose 
    /* eslint-disable no-underscore-dangle */ 
    const composeEnhancers = 
    process.env.NODE_ENV !== 'production' && 
    typeof window === 'object' && 
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ 
     ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ 
     // TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading 
     // Prevent recomputing reducers for `replaceReducer` 
     shouldHotReload: false, 
     }) 
     : compose; 
    /* eslint-enable */ 

    const store = createStore(
    createReducer(), 
    fromJS(initialState), 
    composeEnhancers(...enhancers) 
); 

    // Extensions 
    store.runSaga = sagaMiddleware.run; 
    store.injectedReducers = {}; // Reducer registry 
    store.injectedSagas = {}; // Saga registry 

    // Make reducers hot reloadable, see http://mxs.is/googmo 
    /* istanbul ignore next */ 
    if (module.hot) { 
    module.hot.accept('./reducers',() => { 
     store.replaceReducer(createReducer(store.injectedReducers)); 
    }); 
    } 

    return store; 
} 

reducers.js

/** 
* Combine all reducers in this file and export the combined reducers. 
*/ 

import { fromJS } from 'immutable'; 
import { combineReducers } from 'redux-immutable'; 
import { LOCATION_CHANGE } from 'react-router-redux'; 

import languageProviderReducer from 'containers/LanguageProvider/reducer'; 
import userReducer from 'containers/App/reducer'; 

/* 
* routeReducer 
* 
* The reducer merges route location changes into our immutable state. 
* The change is necessitated by moving to [email protected] 
* 
*/ 

// Initial routing state 
const routeInitialState = fromJS({ 
    location: null, 
}); 

/** 
* Merge route into the global application state 
*/ 
function routeReducer(state = routeInitialState, action) { 
    switch (action.type) { 
    /* istanbul ignore next */ 
    case LOCATION_CHANGE: 
     return state.merge({ 
     location: action.payload, 
     }); 
    default: 
     return state; 
    } 
} 

/*Session reducer*/ 

function sessionReducer (state = {}, action) { 
    switch (action.type) { 
     case 'LOAD_STORED_STATE': 
      return action.storedState; 
     default: 
      return state; 
    } 
} 

/** 
* Creates the main reducer with the dynamically injected ones 
*/ 
export default function createReducer(injectedReducers) { 
    return combineReducers({ 
     route: routeReducer, 
     session: sessionReducer, 
     language: languageProviderReducer, 
     user: userReducer, 

    ...injectedReducers, 
    }); 
} 

답변

1

아무 생각이 왜 state.toJS() 인 myObject 빠른 {}

입니다. 코드 분석에 따르면 redux 저장소를 만들 때 localStorage에서 복원되었습니다. 모든 코드 포인트 initialState은 항상 {}이므로 상점에 빈 오브젝트가 포함될 것으로 예상됩니다.

코드가 리팩토링되어 localStorage 상태를 확인하고로드하거나 병합 할 수 있습니다. 또한 서버 측에서 사전로드 된 상태가 없습니다.

export default function configureStore(initialState = {}, history, session) { 
    // [cut] 
    const store = createStore(
    createReducer(), 
    fromJS(initialState), 
    composeEnhancers(...enhancers) 
); 
    // [cut] 
    return store; 
} 
+0

로컬 저장소에 쿠키가 사용되는 것보다 아무것도 없다면 (이는 redux-session에 대한 설명 이었기 때문에) 더욱 복잡합니다. 나는 어느 정도 당신이 말하는 것을 보지만, 도서관이 처리해야하는 것이 아닌가? 당신이 말하는 것을하기 위해 어떤 좋은 예도 찾을 수 없기 때문에 조금 잃어 버렸습니다 ... redux-session은 약간의 예제 코드를 사용할 수 있습니다 – Codematcha

+0

죄송합니다, 조금 더 가까이 가고 있습니다. 내가 composeEnhancers (... enhancers)가 세션을 복원해야한다고 생각하는 applyMiddleware (세션)에 추가해야하지만 내 이전 코드의 일부로 initialState를 제거했습니다. – Codematcha

+0

저는이 문제가 주를 대신하는 다른 감속기와 충돌한다고 생각합니다. 감사! – Codematcha