Redux-persist: Usage with seamless-immutable

Created on 12 Jul 2016  路  11Comments  路  Source: rt2zz/redux-persist

Hey,
I'm trying to use this library with seamless-immutable.
I created a transform like this:

let immutableTransform = createTransform(
        (inboundState) => inboundState.asMutable? inboundState.asMutable({deep: true}) : inboundState,
        (outboundState) => immutable(outboundState)
    )

But the immutable wrapper around the data seems to get discarded at some point, meaning that my reducers break as they rely on the wrapper methods. Is there anything else I need to add?

Most helpful comment

I know this is closed but if you implement a transformer like this (view the attached code) it works really well.

import R from 'ramda'
import Immutable from 'seamless-immutable'

const isImmutable = R.has('asMutable')

const convertToJs = (state) => state.asMutable({deep: true})

const fromImmutable = R.when(isImmutable, convertToJs)

const toImmutable = (raw) => Immutable(raw)

export default {
  out: (state) => {
    state.mergeDeep = R.identity
    return toImmutable(state)
  },
  in: (raw) => {
    return fromImmutable(raw)
  }
}

All 11 comments

Can anyone comment on this?

Seamless immutable is a popular alternative to immutable.js and a quick how-to would benefit the community.

It seems like the above transform is actually fine, just remember that the initial state must be immutable too or when you merge the persisted state with it problems arise.

@robclouth sorry for the delayed response. As you noted the transforms only work on the reducer level, and so will not maintain immutable top level state. There is an open issue and PR to address this but I want to make sure we get the api right before committing. In the meantime you can always use a custom rehydration reducer or apply the seamless transformation in conjunction wth getStoredState

I know this is closed but if you implement a transformer like this (view the attached code) it works really well.

import R from 'ramda'
import Immutable from 'seamless-immutable'

const isImmutable = R.has('asMutable')

const convertToJs = (state) => state.asMutable({deep: true})

const fromImmutable = R.when(isImmutable, convertToJs)

const toImmutable = (raw) => Immutable(raw)

export default {
  out: (state) => {
    state.mergeDeep = R.identity
    return toImmutable(state)
  },
  in: (raw) => {
    return fromImmutable(raw)
  }
}

For those of you using v5 and having trouble, I grabbed these transformers + whipped up a custom stateReconciler that helps you use seamless-immutable and avoid the dreaded state.merge is not a function error you get when processing actions after rehydration.

Thanks to @josev55 and @robclouth for the original transforms, a variant of which is also included in this lib!

https://github.com/hilkeheremans/redux-persist-seamless-immutable

It seems to be broken now and I am having the same problem merge is not a function even using redux-persist-seamless-immutable. I put a sand box to reproduce:

https://codesandbox.io/s/k5vjmvmpkv

It seems like the problem is with any nested ImmutableSeamless reducer slices. If you make the authReducer a plain javascript, it works. Basically ReduxPersist is trying to add _persist property in a object which has been previously sealed.

@leonardoanalista Thanks for the repro, I'll take a look over the next few days -- let's discuss this further in the issue on my repo.

@hilkeheremans thanks for the custom stateReconciler. Helped a lot.

For anyone with this problem this is how i solved it:

In your persistConfig add a custom transform

  import ImmutablePersistenceTransform from './ImmutablePersistenceTransform'

  const persistConfig = {
    key: 'root',
    storage,
    whitelist: ['account'],
    transforms: [ImmutablePersistenceTransform]
  }

ImmutablePersistenceTransform.js

import R from 'ramda'
import Immutable from 'seamless-immutable'

// this is a transform in order to make redux-persist work with seamless-immutable

// is this object already Immutable?
const isImmutable = R.has('asMutable')

// change this Immutable object into a JS object
const convertToJs = state => state.asMutable({deep: true})

// optionally convert this object into a JS object if it is Immutable
const fromImmutable = R.when(isImmutable, convertToJs)

// convert this JS object into an Immutable object
const toImmutable = raw => Immutable(raw)

// the transform interface that redux-persist is expecting
export default {
  out: (state) => toImmutable(state),
  in: (raw) => fromImmutable(raw)
}

note that you will need to install ramda
npm i --save ramda

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Clumsy-Coder picture Clumsy-Coder  路  3Comments

thenewt15 picture thenewt15  路  3Comments

peteroid picture peteroid  路  4Comments

bockc picture bockc  路  3Comments

admbtlr picture admbtlr  路  3Comments