Josh Choo's blog

Redux: What does serializable mean?

20 October 2021

The Redux site mentions that we should avoid putting non-serializable values in state or actions. But what exactly does Redux consider serializable?

Digging through the Redux source code reveals the use of an isSerializable function that the createSerializableStateInvariantMiddleware function takes as an optional parameter.

By default, Redux will assign an isPlain function to isSerializable.

Let's see how exactly isPlain is implemented.

The following code shows shows that serializable means that it can be serialized to JSON. This includes boolean, number, string, array, plain object or undefined.

/**
* Returns true if the passed value is "plain", i.e. a value that is either
* directly JSON-serializable (boolean, number, string, array, plain object)
* or `undefined`.
*
* @param val The value to check.
*
* @public
*/

export function isPlain(val: any) {
const type = typeof val
return (
type === 'undefined' ||
val === null ||
type === 'string' ||
type === 'boolean' ||
type === 'number' ||
Array.isArray(val) ||
isPlainObject(val)
)
}

/**
* Returns true if the passed value is "plain" object, i.e. an object whose
* prototype is the root `Object.prototype`. This includes objects created
* using object literals, but not for instance for class instances.
*
* @param {any} value The value to inspect.
* @returns {boolean} True if the argument appears to be a plain object.
*
* @public
*/

export default function isPlainObject(value: unknown): value is object {
if (typeof value !== 'object' || value === null) return false

let proto = value
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto)
}

// In Node.js, the root `Object.prototype` is `[Object: null prototype] {}`
return Object.getPrototypeOf(value) === proto
}