State Normalization: Treat Your Store Like a Database
Treat your Redux state like a database. Instead of nesting related data, flatten it into separate 'tables' keyed by ID. This simplifies updates and prevents unnecessary re-renders. The footgun is storing API data as-is, creating update bugs.
WHY IT EXISTS Many APIs return data that is nested or relational, like a blog post that contains user and comment objects. Storing this structure directly in a state management library like Redux creates problems. Updating a piece of data that's duplicated in multiple places is error-prone, and changing a deeply nested value requires complex logic and can trigger unnecessary re-renders of unrelated UI components.
THE MENTAL MODEL Treat a portion of your client-side state as if it were a small, in-memory database. Instead of a single, deeply nested tree, you organize your data into flat lookup tables, similar to how a relational database has tables for users, posts, and comments.
HOW IT WORKS Normalization follows a few simple principles. First, each type of data gets its own "table" in the state, which is an object mapping IDs to data. For example, you'd have a posts object and a comments object. Second, any references between items are stored using the item's ID, not by embedding the entire object. A post would contain an authorId string instead of a full user object. Third, to maintain order (like the order of posts on a feed), you use a separate array of IDs.
WHEN TO USE IT Use normalization whenever your application state includes collections of related data, especially when that data comes from an API. If you have items that can be referenced from multiple places (e.g., a user who authors multiple posts and comments), normalization provides a single source of truth. This makes finding or updating a specific item a fast, simple lookup, and it simplifies your reducer logic immensely.
WHEN NOT TO USE IT Normalization is overkill for simple, non-relational data. If you are managing simple UI state (like isSidebarOpen) or a flat list of items that have no relationships or unique IDs, the added structure of normalization isn't necessary. Stick with simple objects or arrays for those cases.
ONE CANONICAL EXAMPLE An API might return an array of post objects, where each post contains an array of full comment objects. After normalization, your Redux store would have three top-level keys: posts, comments, and users. Each would contain a byId object (the ID-to-item lookup table) and an allIds array for ordering. A specific post object would no longer contain nested comment objects, but rather an array of commentIds, making updates clean and efficient.
Read the original → redux.js.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.