intermediate

Normalization

Store entity graphs by ID to avoid duplicated nested objects, expensive updates, and inconsistent views.

Normalization stores entities by ID in flat maps instead of nested duplicates. When the same user appears in ten lists, one `users.byId` record updates every view.

					// Normalized shape
const state = {
  users: { u1: { id: 'u1', name: 'Ada' } },
  posts: {
    p1: { id: 'p1', authorId: 'u1', title: 'Hello' },
  },
  postsByUser: { u1: ['p1'] },
};
				

| Nested tree | Normalized maps | |-------------|-----------------| | Simple reads in one screen | Many screens share entities | | Risk of stale copies | Single update point | | Easy small prototypes | Selectors join IDs to objects |

`createEntityAdapter` in Redux Toolkit automates CRUD on normalized slices. Join relations in selectors, not by duplicating nested objects on every fetch.

The trade-off is flatter updates and shared entities versus more selector logic and join code at read time.

On interviews: explain when normalization pays off and what selectors must do after a write.

Common pitfalls: premature normalization, orphan IDs after deletes, and denormalized API responses copied verbatim into global state.

Checklist:

  • Entities by ID; relations by ID lists.
  • Update one record; views follow via selectors.
  • Plan cascade rules for deletes.
  • Normalize when duplication hurts, not by default.