Home > Software engineering >  react-native redux-toolkit: a non-serializable value was detected in the state, but my object is ser
react-native redux-toolkit: a non-serializable value was detected in the state, but my object is ser

Time:05-19

I just migrated my old-school react-native with redux App to the modern redux-toolkit and now I have this error:

A non-serializable value was detected in the state, in the path: `currentUserSessionData.data`. Value:, CurrentUserSessionData {
  "isOnboardingDone": false,
}, 
Take a look at the reducer(s) handling this action type: currentUserSessionDataSlice/get/pending.

Which is very strange because the object CurrentUserSessionData is so simple:

class CurrentUserSessionData {
    isOnboardingDone: boolean = false;
}

export default CurrentUserSessionData;

I really think it is serializable!

Also, isn't it strange that the error writes: "Value:comma CurrentUserSessionData"? That comma after : seems strange, and I never defined the pending extra reducer.


I thought I made a mistake in the state or store definitions, I read and read the documentation a lot of times but I don't find the problem!

The slice:

import {createAsyncThunk, createSlice} from '@reduxjs/toolkit'
import * as CurrentUserSessionDataRepository from '../services/CurrentUserSessionDataRepository';
import CurrentUserSessionData from "../models/CurrentUserSessionData";

export const currentUserSessionDataSlice = createSlice({
    name: 'currentUserSessionDataSlice',
    initialState: {
        data: new CurrentUserSessionData(),
    },
    reducers: {},
    extraReducers: build => {

        build.addCase(currentUserSessionDataGetAsync.fulfilled, (state, action) => {
            state.data = action.payload;
        });

    },
});

export const currentUserSessionDataGetAsync = createAsyncThunk(
    "currentUserSessionDataSlice/get",
    async () => {
        return await CurrentUserSessionDataRepository.getCurrentUserSessionData();
    }
)

The data repository:

import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Logger from "./Logger";
import CurrentUserSessionData from "../models/CurrentUserSessionData";

const asyncStorageCurrentUserSessionDataKey: string = "currentUserSessionData";

export const getCurrentUserSessionData = async (): Promise<CurrentUserSessionData> =>
{

    Logger.logDebug('getCurrentUserSessionData');
    const sessionDataRaw = await AsyncStorage.getItem(asyncStorageCurrentUserSessionDataKey);

    if (sessionDataRaw) {
        return JSON.parse(sessionDataRaw) as CurrentUserSessionData;
    }

    return {
        isOnboardingDone: false
    };

};

The store:

import {configureStore} from "@reduxjs/toolkit";
import {combineReducers} from "redux";
import {currentUserSessionDataSlice} from "./currentUserSessionDataSlice";
import {TypedUseSelectorHook, useDispatch, useSelector} from "react-redux";

const appStateStore = configureStore({
    reducer: combineReducers({
        currentUserSessionData: currentUserSessionDataSlice.reducer,
        // ....
    })
});

export default appStateStore;
export type IRootState = ReturnType<typeof appStateStore.getState>;
export type IAppDispatch = typeof appStateStore.dispatch;
export const useAppDispatch = () => useDispatch<IAppDispatch>();
export const useAppSelector: TypedUseSelectorHook<IRootState> = useSelector;

How I dispatch:

import {useAppDispatch} from "./appStateStore/appStateStore";
// ...
const dispatch = useAppDispatch();
await dispatch(currentUserSessionDataGetAsync());
// ...

What am I doing wrong?

CodePudding user response:

Yes, the problem is that it's an actual class. Class instances are not fully serializable, and you effectively never need to use an actual class when writing a React Redux app. Just make that a plain JS object instead.

In other words, instead of this:

    initialState: {
        data: new CurrentUserSessionData(),
    },

Just do:

    initialState: {
        data: {isOnboardingDone: false}
    },

Also, as a side note, you don't have to call combineReducers yourself - configureStore can do it for you.

  • Related