Normalized CRUD state
A slice stores many records keyed by stable IDs and needs standard add, update, remove, and replace operations.
Redux Toolkit · Function
createEntityAdapter generates reducers and selectors for managing normalized collections of entities. It returns an adapter with CRUD operations, initial-state creation, and selector helpers.
createEntityAdapter builds an adapter for a normalized collection. It supplies an initial state shaped as ids plus entities, CRUD case reducers, and memoized selectors; optional selectId chooses each entity's key, while sortComparer controls ID ordering.
createEntityAdapter<T>(options?: { selectId?: (entity: T) => EntityId; sortComparer?: false | ((a: T, b: T) => number) })| Name | Type | Description |
|---|---|---|
options | EntityAdapterOptions<T> | Optional configuration object containing selectId, which returns an entity's unique ID, and sortComparer, which controls entity ordering. |
An entity adapter object containing generated CRUD reducers, the configured selectId and sortComparer callbacks, getInitialState, and selector-generation functions.
import { createEntityAdapter, createSlice } from '@reduxjs/toolkit'
type Book = { id: string; title: string }
const booksAdapter = createEntityAdapter<Book>({
sortComparer: (a, b) => a.title.localeCompare(b.title),
})
const booksSlice = createSlice({
name: 'books',
initialState: booksAdapter.getInitialState(),
reducers: {
booksReceived: booksAdapter.setAll,
bookAdded: booksAdapter.addOne,
},
})
export const { selectAll: selectAllBooks } = booksAdapter.getSelectors(
(state: { books: ReturnType<typeof booksAdapter.getInitialState> }) => state.books,
)Creates a normalized, sorted book collection and uses generated adapter reducers in a slice.
A slice stores many records keyed by stable IDs and needs standard add, update, remove, and replace operations.
A collection should expose reusable selectAll and selectById accessors from a slice or root state.
List rendering requires entities to remain ordered according to a comparison function.
It creates an adapter object containing generated CRUD reducers, an initial-state factory, and selector generators for normalized entities. The standard state shape is an ids array plus an entities lookup object.
Follow-up: How would you sort entities? Pass sortComparer in the options object; it compares entities and keeps the IDs ordered.
Use getInitialState() as the slice's initial state, then use adapter methods such as addOne or setAll as case reducers. The same methods can also act as mutating helpers inside Redux Toolkit reducers.
Follow-up: How can selectors read a nested slice? Pass a root-state selector to getSelectors, which returns selectors such as selectAll and selectById.
By default, the adapter reads entity.id. For a different identifier field, provide selectId, a function that receives an entity and returns its unique ID.
Follow-up: What happens if nested data is passed to an update operation? The operation performs a shallow merge, so nested incoming objects replace existing nested objects.
createSlicecreateReducergetInitialStategetSelectorsaddOneaddManysetAllupdateOne