A non-serializable value was detected in the state
moezbenrebah opened this issue · 2 comments
moezbenrebah commented
I try to normalize my state date, using redux, normalizr, and immutable.js. I have the desired output but it's along with an error:
A non-serializable value was detected in the state
My reducer:
// normalizr
const courses = new schema.Entity("courses");
const coursesNormalizer = (data) => normalize(data, [courses]);
// data to work with
const data = [
{
id: 1,
type: "default",
value: "New course available"
},
{
id: 2,
type: "urgent",
value: "New resume available"
},
{
id: 3,
type: "urgent",
value: "New data available"
}
]
// reducer
const courseReducer = (state=fromJS({}), action) => {
switch (action.type) {
case FETCH_COURSE_SUCCESS:
const normalizedData = coursesNormalizer(action.data);
const { courses } = normalizedData.entities;
Object.keys(courses).map((key) => {
courses[key] = {
...courses[key],
isSelected: false,
};
});
return state.merge(courses);
default:
return state;
}
};
const store = configureStore({reducer:courseReducer});
console.log(store.getState().toJS())
store.dispatch({
type: FETCH_COURSE_SUCCESS,
data
})
console.log(store.getState().toJS())
As I mention above I got the right output but redux complains from a non-realized data, the complete output below:
{}
{
size: 3,
_root: ArrayMapNode {
ownerID: OwnerID {},
entries: [ [Array], [Array], [Array] ]
},
__ownerID: undefined,
__hash: undefined,
__altered: false
}
A non-serializable value was detected in the state, in the path: `<root>`. Value: Map {
size: 3,
_root: ArrayMapNode {
ownerID: OwnerID {},
entries: [ [Array], [Array], [Array] ]
},
__ownerID: undefined,
__hash: undefined,
__altered: false
}
Take a look at the reducer(s) handling this action type: FETCH_COURSE_SUCCESS.
(See https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state)
{
'1': {
id: 1,
type: 'default',
value: 'New course available',
isSelected: false
},
'2': {
id: 2,
type: 'urgent',
value: 'New resume available',
isSelected: false
},
'3': {
id: 3,
type: 'urgent',
value: 'New data available',
isSelected: false
}
}
markerikson commented
RTK does not recognize Immutable.js values as non-serializable by default.
The best option here is to not use Immutable.js, and instead use plain JS values with Immer:
- https://redux.js.org/style-guide/#use-immer-for-writing-immutable-updates
- https://redux.js.org/style-guide/#use-plain-javascript-objects-for-state
- https://redux-toolkit.js.org/usage/immer-reducers
Failing that, you could technically configure the serializability middleware to recognize Immutable.js values as acceptable:
But I'd really recommend against using Immutable.js.
moezbenrebah commented
Ok, thank you @markerikson