How to use immutable.js with RTK (redux toolkit)? #3539
-
I'm migrating legacy Redux code to RTK. With my legacy code base I was using Immutable.js (for immutability purposes), I don't need it anymore for the new code I'm gonna write, but I would like for the legacy code to keep working without touching it, and while using
I get it, it's because I change the object instance, I can disable the error doing so : immutableCheck: false,
serializableCheck: false, but IMO it disables too much, I would like to keep these settings on, but for Immutable.js to bypass the immutability check. // Augment middleware to consider Immutable.JS iterables serializable
const isSerializable = (value) =>
Iterable.isIterable(value) || isPlain(value)
const getEntries = (value) =>
Iterable.isIterable(value) ? value.entries() : Object.entries(value)
const serializableMiddleware = createSerializableStateInvariantMiddleware({
isSerializable: () => true // all values will be accepted
isSerializable,
getEntries,
})
const store = configureStore({
reducer,
middleware: [serializableMiddleware]
}) here https://github.com/reduxjs/redux-toolkit/pull/141/files but it's not working, Now the file looks like this : https://github.com/reduxjs/redux-toolkit/blob/master/docs/api/otherExports.mdx, there's no trace of Immutable.js. What can I do ? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 5 replies
-
the serializableCheck and immutableCheck are two separate checks, and we want you to customise them using For example, something like the below (untested) code might work: import { configureStore, isImmutableDefault, isPlain } from "@reduxjs/toolkit";
import { isImmutable } from "immutable";
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
immutableCheck: {
isImmutable: (value) => isImmutable(value) || isImmutableDefault(value),
},
serializableCheck: {
isSerializable: (value) => isImmutable(value) || isPlain(value),
getEntries: (value) =>
isImmutable(value) ? value.entries() : Object.entries(value),
},
}),
}); |
Beta Was this translation helpful? Give feedback.
-
Hi, Immutablejs maintainer here 👋 I'm playing with RTK today in order to migrate a "legacy" redux stack to RTK. I saw that redux-toolkit does use immer for state management and that is not gonna change, I understand totally as state management is complicated 😄 middleware configurationI encountered the same warning in the console, and @EskiMojo14 trick seems to work. From my first tests, it seems that the only configuration needed is the export const store = configureStore({
reducer: {
counter: counterReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
// does not seems needed
// immutableCheck: {
// isImmutable: (value: any) =>
// isImmutable(value) || isImmutableDefault(value),
// },
// ignore error for immutable value
serializableCheck: {
isSerializable: (value: any) => isImmutable(value) || isPlain(value),
getEntries: (value: any) =>
isImmutable(value)
? value.entries()
: Object.entries(value),
},
}),
}) There is a TypeScript issue on As a matter of fact, I could expose a helper utility in immutable that helps user to configure the middleware. tested casesFull immutable stateFull immutable state seems to work fine with the immutable API. - state.status = 'loading';
+ return state.set("status", "loading"); object state with an immutable partA more tricky state is an object state that does contain parts of immutable objects. It does seems to work too. The code is weirder thought as it does mix immer and immutable logic. - state.status = 'loading';
+ state.immutable = state.immutable.set("state", "loading") typescript issueThe main issue I faced is with Typescript. Despite the fact that runtime seems to work, I'm stuggled with TypeScript here: If I have an immutable object, I got error because immer types seems to "convert" anything to With an object:
With a list:
It may be caused by Classes should be made draftable or not mutated (and complex object management). I do not know how this issue can be solved, as everything I tested seems to work. Do you think it's something related to redux-toolkit package, or immer itself ? Further discussionI read a lot of your updated documentation and some issues closed on users that would like to make immer optional. As I said, I do understand fully your point: state management is hard, immutability is key in react, and immer does have an API that is close to the Javascript API. But on the other hand, immutable was really used with redux (and is still really used : 16M download per week). Do you see a path where we can make immutable "first-class" with redux ? maybe by allowing any other immutability library as a plugin or something like that ? It might accelerate the transition to RTK. I am willing to help here if you think that it's doable. I understand if you do not want to go in this path though. In this case I will try to make RTK working with immutable on my side by fixing the previous issues. Thank you ! |
Beta Was this translation helpful? Give feedback.
the serializableCheck and immutableCheck are two separate checks, and we want you to customise them using
getDefaultMiddleware
.For example, something like the below (untested) code might work: