Support circular references in persistState

This commit is contained in:
Zalmoxisus 2016-04-18 16:28:08 +03:00
parent 25eab60562
commit c87cf33c59
3 changed files with 25 additions and 2 deletions

View File

@ -61,6 +61,7 @@
"react": "^0.14.0 || ^15.0.0-rc.1" "react": "^0.14.0 || ^15.0.0-rc.1"
}, },
"dependencies": { "dependencies": {
"jsan": "^3.1.2",
"lodash": "^4.2.0", "lodash": "^4.2.0",
"react-redux": "^4.0.0", "react-redux": "^4.0.0",
"redux": "^3.2.1" "redux": "^3.2.1"

View File

@ -1,5 +1,6 @@
import mapValues from 'lodash/mapValues'; import mapValues from 'lodash/mapValues';
import identity from 'lodash/identity'; import identity from 'lodash/identity';
import jsan from 'jsan';
export default function persistState(sessionId, deserializeState = identity, deserializeAction = identity) { export default function persistState(sessionId, deserializeState = identity, deserializeAction = identity) {
if (!sessionId) { if (!sessionId) {
@ -28,7 +29,7 @@ export default function persistState(sessionId, deserializeState = identity, des
try { try {
const json = localStorage.getItem(key); const json = localStorage.getItem(key);
if (json) { if (json) {
finalInitialState = deserialize(JSON.parse(json)) || initialState; finalInitialState = deserialize(jsan.parse(json)) || initialState;
next(reducer, initialState); next(reducer, initialState);
} }
} catch (e) { } catch (e) {
@ -48,7 +49,7 @@ export default function persistState(sessionId, deserializeState = identity, des
store.dispatch(action); store.dispatch(action);
try { try {
localStorage.setItem(key, JSON.stringify(store.getState())); localStorage.setItem(key, jsan.stringify(store.getState()));
} catch (e) { } catch (e) {
console.warn('Could not write debug session to localStorage:', e); console.warn('Could not write debug session to localStorage:', e);
} }

View File

@ -88,6 +88,27 @@ describe('persistState', () => {
expect(store2.getState()).toBe(-2); expect(store2.getState()).toBe(-2);
}); });
it('should work with objects with circular references', () => {
const circularReducer = (state = { count: 0 }, action) => {
if (action.type === 'INCREMENT') {
const obj = { count: state.count + 1 };
obj.self = obj;
return obj;
}
return state;
};
const store = createStore(circularReducer, compose(instrument(), persistState('id')));
expect(store.getState().count).toBe(0);
store.dispatch({ type: 'INCREMENT' });
store.dispatch({ type: 'INCREMENT' });
expect(store.getState().count).toBe(2);
const store2 = createStore(circularReducer, compose(instrument(), persistState('id')));
expect(store2.getState().count).toBe(2);
});
it('should warn if read from localStorage fails', () => { it('should warn if read from localStorage fails', () => {
const spy = expect.spyOn(console, 'warn'); const spy = expect.spyOn(console, 'warn');
delete global.localStorage.getItem; delete global.localStorage.getItem;