Non-Serializable Value Error in Redux Toolkit State
Why This Error Occurs
Redux Toolkit includes middleware that automatically checks for non-serializable values in your state and actions. This error occurs when your Redux state contains values that cannot be serialized - typically class instances, functions, Promises, or other complex objects.
The error message points to the specific path in your state where the non-serializable value was detected:
A non-serializable value was detected in the state, in the path: `varietals.red.0`.Root Cause: Class Instances in State
The most common cause is storing class instances in your Redux state. In your case:
class Varietal {
constructor(id, color, varietal, isSelected, isCommon) {
this.id = id;
this.color = color;
this.varietal = varietal;
this.isSelected = isSelected;
this.isCommon = isCommon;
}
}
// This creates non-serializable class instances
const createVarietalArray = (arr, color, isCommon) =>
arr.map(v => new Varietal(uuidv5(v, NAMESPACE), color, v, false, isCommon));Class instances contain prototype chains and potential methods that cannot be properly serialized with JSON.stringify(), which Redux uses internally.
Recommended Solution: Use Plain Objects
Replace class instances with plain JavaScript objects:
// Use plain objects instead of class instances
export const createVarietalArray = (arr, color, isCommon) =>
arr.map(v => ({
id: uuidv5(v, NAMESPACE),
color,
varietal: v,
isSelected: false,
isCommon,
}));This approach maintains the same data structure but uses serializable plain objects instead of class instances.
Alternative Approaches
1. Disable Serialization Check (Not Recommended)
You can disable the serialization check middleware, but this is generally not advised:
import { configureStore } from '@reduxjs/toolkit';
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
}),
});WARNING
Disabling serialization checks removes an important safeguard and may lead to hard-to-debug issues in your application.
2. Selective Ignoring of Actions or Paths
A better alternative is to selectively ignore specific actions or paths:
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: ['your/action/type'],
ignoredActionPaths: ['meta.arg', 'payload.timestamp'],
ignoredPaths: ['items.dates'],
},
}),
});3. Using with Redux Persist
If you're using Redux Persist, include these specific ignored actions:
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist';
import storage from 'redux-persist/lib/storage';
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
});
export const persistor = persistStore(store);Best Practices
- Use Plain JavaScript Objects: Redux state should contain only serializable data
- Keep State Minimal: Store only the data needed for your UI
- Use Selectors for Derived Data: Compute derived data in selectors rather than storing it
- Normalize Data: Use normalized state shape for better performance
TIP
While you can disable serialization checks, the recommended approach is to fix the underlying issue by ensuring your state contains only serializable values.
When to Use Non-Serializable Values
There are limited cases where non-serializable values might be acceptable:
- When using with Redux Persist (with the specific ignored actions shown above)
- When dealing with unique identifiers like UUIDs that have specific formatting requirements
- When using middleware that handles serialization internally
Even in these cases, it's better to handle serialization at the boundary of your Redux store rather than storing non-serializable values directly in the state.
Summary
The "non-serializable value" error in Redux Toolkit is a helpful warning that prevents common Redux anti-patterns. The optimal solution is to refactor your code to use plain JavaScript objects instead of class instances in your Redux state. While workarounds exist to disable the checks, they remove important safeguards and should be used sparingly and with caution.