elgerlambert / redux-localstorage

Store enhancer that syncs (a subset) of your Redux store state to localstorage.
MIT License
1.32k stars 107 forks source link

Using Immutable.js state with redux-localstorage #22

Closed localhosted closed 8 years ago

localhosted commented 8 years ago

I'm not sure how to setup the config parameter to properly use an Immutable object, This is how I configure the options:

import Immutable from 'immutable';

export const LocalStorageConfig = {
    serialize: (subset) => subset.toJson(),
    deserialize: (serializedData) => Immutable.fromJS(JSON.parse(serializedData)),
    merge: (initialState, persistedState) => initialState.mergeDeep(persistedState)
};

But I get an error with my selector, state.get is not a function :

export const menuSelector = createSelector(
    mainSelector,
        (state) => ({
            menu: state.get('menu')
    })
);

It looks like I'm missing something here.

localhosted commented 8 years ago

My mistake, I wasn't importing it correctly. : (

elgerlambert commented 8 years ago

Hi @localhosted, Had a busy week last week, glad to hear you managed to resolve your issue! Good luck!

qingweibinary commented 8 years ago

Hi, may I know how you fixed your problem?

kretz commented 8 years ago

Yep, all full example of redux-localstorage with immutablejs would be appreciated.

localhosted commented 8 years ago

I ended up using 1.0.0-rc4, otherwise it becomes a bother to merge previous state with the initial state:

const storage = compose(
    filter('key')
)(adapter(window.localStorage));

let reducer = compose(
    mergePersistedState((initialState, persistedState) => {
      initialState.key = initialState.key.mergeDeep(Immutable.fromJS(persistedState.key));
      return initialState;
    })
)(rootReducer);

finalCreateStore = compose(
    applyMiddleware(logger, thunk),
    reduxReactRouter({routes, createHistory}),
    persistState(storage, 'key')
)(createStore);

const store = finalCreateStore(reducer);
elgerlambert commented 8 years ago

Hi @qingweibinary, @kretz, does the comment above provide sufficient insight, did it solve your issues?

If you still have questions could you provide a little more info, what version are you using and what isn't working as expected?

kretz commented 8 years ago

I got it to work with the following, which is changed from the initial comment. Also, I was tripped up when combining this with combineReducers and removed it.


const loggerMiddleware = createLogger();

const localStorageConfig = {
  slicer: (paths) => (state) => state.filter((v,k) => paths.indexOf(k) > -1),
  serialize: (subset) => JSON.stringify(subset.toJS()),
  deserialize: (serializedData) => Immutable.fromJS(JSON.parse(serializedData)),
  merge: (initialState, persistedState) => initialState.mergeDeep(persistedState)
};

const createPersistentStore = compose(
  persistState(['userId', 'idToken'], localStorageConfig),
  applyMiddleware(
    thunkMiddleware,
    loggerMiddleware
  )
)(createStore);

const store = createPersistentStore(rootReducer);
qingweibinary commented 8 years ago

@elgerlambert I figured it out, thanks for your help ;)

NameFILIP commented 8 years ago

I've improved slicer from the previous example.

const localStorageConfig = {
  slicer: (paths) => (state) => (paths ? state.filter((v, k) => paths.indexOf(k) > -1) : state),
  serialize: (subset) => JSON.stringify(subset.toJS()),
  deserialize: (serializedData) => Immutable.fromJS(JSON.parse(serializedData)),
  merge: (initialState, persistedState) => initialState.mergeDeep(persistedState),
};

Use-case:

persistState(undefined, localStorageConfig)