Normalized entity storage
Model a collection of records in a slice using the standard normalized IDs-plus-entities structure.
Redux Toolkit · Type Alias
EntityAdapter is the plain-object adapter type for one normalized entity collection. It bundles CRUD reducers, identity and sorting configuration, initial-state creation, and memoized selector generation.
EntityAdapter is the plain-object type returned by createEntityAdapter. It groups generated CRUD case reducers, the configured identity and sorting callbacks, initial-state creation, and selector-generation methods for one normalized entity type.
type EntityAdapter<T, Id extends EntityId> = EntityStateAdapter<T, Id> & EntitySelectors<T, Id>An EntityAdapter instance: a plain object containing generated CRUD reducers, the configured callbacks, getInitialState, and selector-generation functions.
import { createEntityAdapter, type EntityAdapter } from '@reduxjs/toolkit'
type User = { id: string; name: string }
const users: EntityAdapter<User> = createEntityAdapter<User>()
const state = users.getInitialState()
users.addOne(state, { id: '1', name: 'Ada' })
console.log(users.getSelectors().selectAll(state))The adapter is typed as EntityAdapter<User>, then used to create normalized state and add an entity.
Model a collection of records in a slice using the standard normalized IDs-plus-entities structure.
Reuse generated add, update, replace, upsert, and remove operations instead of writing collection reducers manually.
Create memoized select-all and select-by-ID accessors for a collection or a nested slice.
EntityAdapter is the adapter instance type produced by createEntityAdapter. It exposes the generated reducers, the configured selectId and sortComparer callbacks, getInitialState, and selector-generation methods.
Follow-up: Why use an adapter instead of handwritten normalized reducers? It standardizes the normalized state shape and supplies reusable CRUD reducers and memoized selectors.
Its CRUD methods operate on an entity state containing IDs and an entity lookup table. Methods include operations such as addOne, setAll, updateOne, upsertMany, and removeMany.
Follow-up: How can those methods be used in a slice? Pass them as case reducers or invoke them as mutating helpers inside Immer-backed reducer logic.
The adapter can generate selectors for normalized data, including selectors for all entities and an entity by ID. getInitialState creates the empty normalized state used by those selectors and reducers.
Follow-up: How can the adapter be scoped to a nested slice? Supply a selector that returns that slice to getSelectors, producing selectors rooted at the Redux state.
createEntityAdapterEntityStateEntitySelectorsEntityStateAdaptercreateSlicecreateReducer