skip to Main Content

Previously i was trying to persist my redux store using the following code:

import AsyncStorage from '@react-native-async-storage/async-storage'
import { persistStore, persistReducer } from 'redux-persist';
import { configureStore, combineReducers } from "@reduxjs/toolkit";
import {searchReducer} from "./search/searchSlice"
import {userReducer} from "./user/userSlice"

const combinedReducers = combineReducers({
    search: searchReducer,
    user: userReducer
})

const persistedReducer = persistReducer({
    key: "root",
    storage: AsyncStorage,
    whitelist: ['user'],
    blacklist: ['search']
}, combinedReducers)

export const store = configureStore({
    reducer: persistedReducer
})

export const persistor = persistStore(store)

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

But i got: error:

R  A non-serializable value was detected in an action, in the path: `register`. Value: [Function register] 

After a LOT of researching, i found the solution in

https://github.com/rt2zz/redux-persist/issues/1439

and at the official docs at the very end of the official docs guide (the issue definitely should definitely be more exposed there). So i modified my code to the following and everything worked:

import AsyncStorage from '@react-native-async-storage/async-storage'
import {
    persistStore,
    persistReducer,
    FLUSH,
    REHYDRATE,
    PAUSE,
    PERSIST,
    PURGE,
    REGISTER,
} from 'redux-persist'
import { configureStore, combineReducers } from '@reduxjs/toolkit'
import { searchReducer } from './search/searchSlice'
import { userReducer } from './user/userSlice'

const combinedReducers = combineReducers({
    search: searchReducer,
    user: userReducer,
})

const persistedReducer = persistReducer(
    {
        key: 'root',
        storage: AsyncStorage,
        whitelist: ['user'],
        blacklist: ['search'],
    },
    combinedReducers
)

export const store = configureStore({
    reducer: persistedReducer,
    middleware: (getDefaultMiddleware) =>
        getDefaultMiddleware({
            serializableCheck: {
                ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
            },
        }),
})

export const persistor = persistStore(store)

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch  

Now, what is triggering me that i don’t understand, is that i didn’t see this approach anywhere in the tutorials i watched and not even in my paid react course. But it worked for ALL OF THEM, without using the middleware with all those obscure imports. One example:

https://www.youtube.com/watch?v=b88Z5POQBwI

His approach is almost identical to my first code here, and everything worked for him as it did for everyone. I would like to understand why it worked for them but didn’t for me.

(one reason being that obviously the implementation without the middleware and all these random (at a fisrt glance) looks a lot cleaner and more easier to understand what is going on)

2

Answers


  1. Please try this approach.

    import { Iterable } from 'immutable'
    import {
      configureStore,
      createSerializableStateInvariantMiddleware,
      isPlain,
      Tuple,
    } from '@reduxjs/toolkit'
    import reducer from './reducer'
    
    // Augment middleware to consider Immutable.JS iterables serializable
    const isSerializable = (value: any) =>
      Iterable.isIterable(value) || isPlain(value)
    
    const getEntries = (value: any) =>
      Iterable.isIterable(value) ? value.entries() : Object.entries(value)
    
    const serializableMiddleware = createSerializableStateInvariantMiddleware({
      isSerializable,
      getEntries,
    })
    
    const store = configureStore({
      reducer,
      middleware: () => new Tuple(serializableMiddleware),
    })
    

    https://redux-toolkit.js.org/api/serializabilityMiddleware

    Login or Signup to reply.
  2. These were just warnings, but even while the warnings were shown, your code already worked.

    It’s not that non-serializable values immediately break things, they should just be avoided when possible as they can cause problems.

    You now took the necessary step to disable the warnings, but are still effectively running the same code as before apart from the disabled warnings.

    Your tutorial never showed the console, so the warnings were not visible.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search