Redux - Where to keep non-serializable Data?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
The short answer is: keep non-serializable data out of Redux state whenever possible. Redux works best when the store contains plain serializable values such as objects, arrays, strings, numbers, and booleans. Live objects such as class instances, DOM nodes, promises, sockets, and mutable library handles usually belong in component state, refs, middleware, or dedicated service modules instead.
Why Redux Cares About Serializability
Redux tooling assumes state and actions can be inspected, copied, logged, persisted, and replayed.
That is why serializable state matters for:
- Redux DevTools
- persistence and rehydration
- predictable debugging
- time-travel inspection
If you put a WebSocket object, a function, or a Map full of mutable instances into the store, these workflows become harder or impossible.
What Should Stay In Redux
Redux should store the serializable facts about the world, not the live process object itself.
Good Redux state:
Bad Redux state:
The good version stores the app state you care about. The bad version stores live runtime objects that are hard to replay, serialize, or reason about.
Keep Live Objects In Middleware Or Services
A common home for non-serializable resources is middleware or a plain service module.
Example WebSocket manager:
Here Redux stores the connection status and received messages, while the actual socket instance lives outside the store.
That is the normal architecture.
Use React State Or Refs For UI-Local Non-Serializable Data
If the data belongs only to one component, keep it in component state or a ref rather than pushing it into Redux.
A DOM node or media element reference has no business in Redux. It is local UI runtime state, not application state.
Convert When A Serializable Representation Exists
Sometimes the non-serializable value has a clean serializable form.
Examples:
- '
Datebecomes an ISO string or timestamp' - '
Setbecomes an array' - '
Mapbecomes a plain object or array of entries'
Example:
This is often the best compromise: keep the store serializable, and reconstruct richer objects at the usage boundary when needed.
Redux Toolkit Warns You For A Reason
Redux Toolkit includes serializability checks in development. If you see warnings about non-serializable values in state or actions, the right first reaction is usually not to disable the check.
The better question is:
- should this value live somewhere else
- or should I convert it to a plain representation first
Only relax the check when you fully understand why the non-serializable value is present and why the tradeoff is acceptable.
A Good Rule Of Thumb
Store in Redux:
- IDs
- plain objects
- arrays
- status flags
- timestamps or strings
Keep outside Redux:
- sockets
- promises
- DOM nodes
- class instances with behavior
- mutable controllers and handles
That rule solves most of the ambiguity.
Common Pitfalls
The biggest mistake is putting live service objects into Redux because they are globally relevant. Global relevance does not automatically mean global state.
Another mistake is storing Date, Map, Set, or class instances directly when a plain serializable representation would work better.
People also disable Redux Toolkit's serializable warnings too quickly instead of treating them as architecture feedback.
Finally, do not confuse application state with process handles. Redux should store what happened and what the UI should reflect, not the imperative objects that make it happen.
Summary
- Keep non-serializable runtime objects out of Redux state whenever possible.
- Store serializable facts in Redux and keep live objects in middleware, services, refs, or component-local state.
- Convert values such as
Date,Set, orMapinto plain serializable forms when practical. - Treat Redux Toolkit serializability warnings as useful design signals.
- A good Redux store describes state, not the live machinery behind it.
Related reading
- Redux How to unit test an async action that dispatches another async action
- Redux saga how to put a yield put inside an event listener?
- Relation between CommonJS, AMD and RequireJS?
- Reloading code in a dockerized node.js app with docker-compose
- Remotely debugging my node app that is hosted on AWS
- Remove accents/diacritics in a string in JavaScript
- Remove all child elements of a DOM node in JavaScript
- Remove an onclick listener
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.