Hi folks 👋,
I just installed the redux-persist in a project still in its early stages and I'm facing this error message in the console as first thing when the page loads. I haven't done much besides including the lib as is, and my reducers are pretty simple for now, so I believe it has something to do with redux-persist itself?
Error:
index.js:1446 A non-serializable value was detected in an action, in the path: `register`. Value: ƒ register(key) {
_pStore.dispatch({
type: _constants__WEBPACK_IMPORTED_MODULE_2__["REGISTER"],
key: key
});
}
Code above is followed by this message:
SS of the whole thing:

Could anyone help me pointing me in the right direction? It does not break the application, but the error message is there in the console.
Cheers,
Are you using redux-starter-kit? It looks like the message is caused by the included serializable-state-invariant-middleware (https://redux-starter-kit.js.org/api/getdefaultmiddleware).
As far as I can tell, passing the register and rehydrate functions in the action is central to how redux-persist currently works, but the message can be suppressed by modifying the store configuration to not include that particular middleware function.
That is exactly what is going on. Further investigating I noticed this in the default middleware. I'll just remove the middleware, since it's not really essential to what I'm doing.
Cheers!
@rseemann How exactly did you solve this? Please post your configureStore function.
@SeedyROM I removed the getDefaultMiddleware from the list of middlewares. There is no real fix there, it is a problem between opinions. The serializable-state-invariant-middleware complains when it sees a non-serializable object, a function in this case, being passed as an action; redux-persist needs to do so. Sometimes you just have to pick a side 🤷♀️ .
Anyway, here's my configureStore.
const store = configureStore({
reducer: rootReducer,
middleware: [thunk, logger]
})
@rseemann Where exactly are you getting thunk and logger from, I saw that in the documentation but I was a little bit lost. Did you manually configure them both?
Still a redux noob! Sorry!
@rseemann I was also having issues with PersistGate never rendering, did you run into anything of the sort? I know this probably isn't the place to ask this, but I'm sleepy and desperate.
@SeedyROM I'm using them as they come, no custom config.
import logger from 'redux-logger'
import thunk from 'redux-thunk'
You might have to install those yourself, although I believe redux-starter-kit will have them already, I think it is better to have more atomic dependencies.
About the PersistGate error you mentioned, I never saw this, I'm sorry. Also, don't code while sleepy, man! hahaha
@rseemann I figured that was what was needed, but I wanted to make sure instead of battling against some configuration misunderstanding.
Yeah the PersistGate issue is strange, I'll figure it out in the morning. I don't normally do professional work this late, but dead lines my dude. lol (Don't worry, I'm quarantined in a feature branch haha)
Same issue for me, redux-persist is using default redux configuration and redux-starter-kit is waiting for a string.
It would be nice to have a property into configureStore like persist: true inside redux-starter-kit and handling this error by using the immer pattern from redux-starter-kit
ty @rseemann
We're not going to modify configureStore to offer options specific to redux-persist. If the serializability check is an issue, you have the ability to modify the store setup by changing the included middleware to either leave it out or customize what fields it inspects.
There's a solution since [email protected]
Now you can opt-out the serialization using serializableCheck attr:
import { configureStore, getDefaultMiddleware } from 'redux-starter-kit'
// ...
export const store = configureStore({
reducer,
middleware: getDefaultMiddleware({
serializableCheck: false,
}),
})
Or, ignore a specific action type for the check:
export const store = configureStore({
reducer,
middleware: getDefaultMiddleware({
serializableCheck: {
ignoredActions: [someReduxPersistActionType]
}
}),
})
For anyone else struggling to find out what [someReduxPersistActionType] should be, here's my redux-starter-kit & redux-persist config
import React from "react";
import ReactDOM from "react-dom";
import { configureStore, getDefaultMiddleware } from "redux-starter-kit";
import { Provider } from "react-redux";
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER
} from "redux-persist";
import storage from "redux-persist/lib/storage";
import { PersistGate } from "redux-persist/integration/react";
import App from "./App";
import rootReducer from "./reducers";
const persistConfig = {
key: "root",
version: 1,
storage
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
}
})
});
let persistor = persistStore(store);
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);
@aldreth Thanks for the code 👍
I am using redux-persist with redux toolkit.
here is my store configuration.
I haven't implemented or configured store before.
I intend to persist user state after login.
Currently after login, if I reload app in emulator it always goes back to login screen.
is my store configured properly?
import {configureStore} from '@reduxjs/toolkit';
import authReducer from '../features/login/authSlice';
import AsyncStorage from '@react-native-community/async-storage';
import {persistReducer, persistStore} from 'redux-persist';
import {combineReducers} from 'redux';
import hardSet from 'redux-persist/lib/stateReconciler/hardSet';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
const reducers = combineReducers({
auth: authReducer,
// other reducers goes here...
});
const persistConfig = {
key: 'root',
storage: AsyncStorage,
// stateReconciler: hardSet,
};
const _persistedReducer = persistReducer(persistConfig, reducers);
export const store = configureStore({
reducer: _persistedReducer,
});
export const persistor = persistStore(store);
Here in index.js, I use PersistGate
import React from 'react';
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import {store, persistor} from './src/stores/store';
import {Provider} from 'react-redux';
import {storeUser, storeRefreshToken} from './src/features/login/authSlice';
import {PersistGate} from 'redux-persist/lib/integration/react';
const RNRedux = () => (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
AppRegistry.registerComponent(appName, () => RNRedux);

@rikinshah23 You need to configure the store as in my comment above
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER]
}
})
});
@aldreth Thanks I was able to solve the issue. I was directed to your solution and had help from @markerikson on a separate thread that I created.
For anyone else struggling to find out what
[someReduxPersistActionType]should be, here's myredux-starter-kit&redux-persistconfigimport React from "react"; import ReactDOM from "react-dom"; import { configureStore, getDefaultMiddleware } from "redux-starter-kit"; import { Provider } from "react-redux"; import { persistStore, persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from "redux-persist"; import storage from "redux-persist/lib/storage"; import { PersistGate } from "redux-persist/integration/react"; import App from "./App"; import rootReducer from "./reducers"; const persistConfig = { key: "root", version: 1, storage }; const persistedReducer = persistReducer(persistConfig, rootReducer); const store = configureStore({ reducer: persistedReducer, middleware: getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER] } }) }); let persistor = persistStore(store); ReactDOM.render( <Provider store={store}> <PersistGate loading={null} persistor={persistor}> <App /> </PersistGate> </Provider>, document.getElementById("root") );
This should be added to README here regarding the compatibility between redux-persist and redux-toolkit and redux-starter-kit, because redux-toolkit and redux-starter-kit are pretty commonly used.
We just added a section on this to the RTK Usage Guide page, here:
https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist
How would something like await persistor.flush() be called in a slice? It seems that if I import persistor from the store, the reducer no longer works.
+ import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
export const store = configureStore({
reducer: persistedReducer,
+ middleware: getDefaultMiddleware({
+ serializableCheck: {
+ ignoredActions: ["persist/PERSIST"],
},
}),
});
for me this fixed the issue.
Most helpful comment
For anyone else struggling to find out what
[someReduxPersistActionType]should be, here's myredux-starter-kit&redux-persistconfig