Redux-persist: Issue with immutable map even after using redux-persist-transform-immutable?

Created on 4 Dec 2017  路  10Comments  路  Source: rt2zz/redux-persist

Hey there,

I am writing a react-native app that has an object (not map) top-level state, with immutable map sub state.

My config and reducer:
`const config = {
transforms: [immutableTransform()],
key: 'root',
storage: AsyncStorage,
blacklist: ['nav'],
debug: true
}

const AppReducer = persistCombineReducers(config, {
nav: navigationReducer,
documents: DocumentsReducer,
});
`

Document looks like this:
`export type DocumentEntry = {
id: string,
name: string,
localFullPicture: string,
localThumbail: string,
//tagIds: List,
};

const initDocuments : Map = Map({
d1: {
id: 'd1',
localFullPicture: '',
localThumbnail: '',
name: 'd1',
//tagIds: List(['t1']),
},
d2: {
id: 'd2',
localFullPicture: '',
localThumbnail: '',
name: 'd2',
//tagIds: List(['t1']),
}
});
`

When I close the app and re-open, I see this error:

error TypeError: One of the sources for assign has an enumerable key on the prototype chain. Are you trying to assign a prototype property? We don't allow it, as this is an edge case that we do not support. This error is a performance optimization and not spec compliant.
at Object.assign (C:redactednode_modulesreact-nativeLibrariespolyfillsObject.es6.js:57)
at C:redactednode_modulesredux-persistlibstateReconcilerautoMergeLevel2.js:26
at Array.forEach ()
at autoMergeLevel2 (C:redactednode_modulesredux-persistlibstateReconcilerautoMergeLevel2.js:16)
at C:redactednode_modulesredux-persistlibpersistReducer.js:110
at dispatch (C:redactednode_modulesreduxlibcreateStore.js:178)
at Object.dispatch (C:redactednode_modulesredux-loggerdistredux-logger.js:1)
at Object.rehydrate (C:redactednode_modulesredux-persistlibpersistStore.js:98)
at C:redactednode_modulesredux-persistlibpersistReducer.js:76
at tryCallOne (C:redactednode_modulespromisesetimmediatecore.js:37)

Any advice? In chrome debug tools, I can see that the map shows up as a map (if I don't use the immutable transform, it does not show up as a map).

Most helpful comment

This is probably an issue with state reconciler that can't handle immutable store. You can apply a custom function in persistConfig:
const persistConfig = { key: 'root', storage, stateReconciler: autoMergeLevel2Immutable, transforms: [immutableTransform()] }
See this gist for a custom function

All 10 comments

Hi, @choenden have you found a workaround? I have the same issue after upgrade from v4 to v5

Hi, @choenden, I have the same issue as you. Have you made it work?

I'm stuck with similar store structure, after persist/PERSIST and persist/REHYDRATE dispatched upon app start, my immutable slice of store turns from Map to an object with a size key. persistReducer with redux-persist-transform-immutable config doesn't seem to help. Am I missing something?

This is probably an issue with state reconciler that can't handle immutable store. You can apply a custom function in persistConfig:
const persistConfig = { key: 'root', storage, stateReconciler: autoMergeLevel2Immutable, transforms: [immutableTransform()] }
See this gist for a custom function

I've faced the same problem. After state rehydration, some of my Map structures are broken. I've try the @appelstroop solution, but it didn't help me at all :(

@Macstyg What error or warning is logged to the console?

I have an error from my internal function. In general my state before the closing app is something like that:
itemA: { itemB: Immutable.Map(), itemC: Immutable.Map(objectId, {...}), }
and after the rehydration it became:
itemA: { itemB: { 0: 'itemB', 1: [] }, itemC: { 0: 'itemC', 1: ['objectId', {...}] } }
But I find out that this happens only after some specific user interactions in my application. Network interruption during the messages exchanging through the WebSockets between client and server. I get the warning from the android, and I think that violates the storage.

@Macstyg wild guess, I had trouble initially using autoMergeLevel2Immutable because I had a mix of immutable and plain objects on the first level of my store 馃槄. Thanks for the good gist @appelstroop

@appelstroop -- YAS. This is kickass, the only thing that solved my issue.

If someone is using seamless-immutable the gist will not work as it's, you will need to change line 27 to use .asMutable() instead of .toJS()

Was this page helpful?
0 / 5 - 0 ratings