reduxjs/redux

A non-serializable value was detected in the state

moezbenrebah opened this issue · 2 comments

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
  }
}

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:

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.

Ok, thank you @markerikson