Supports Immutable Updates
Redux encourages immutable updates to the state, where modifications create new state objects instead of mutating the existing state. Normalization aligns well with this approach, as it promotes updating entities immutably while maintaining referential integrity.
Example: This example where you have a normalized state for managing users and posts data:
{
users: {
byId: {
'user1': { id: 'user1', name: 'John Doe' },
'user2': { id: 'user2', name: 'Jane Smith' },
// More user entities...
},
allIds: ['user1', 'user2'] // Array of all user IDs
},
posts: {
byId: {
'post1': { id: 'post1', title: 'Redux Benefits', author: 'user1' },
'post2': { id: 'post2', title: 'State Normalization', author: 'user2' },
// More post entities...
},
allIds: ['post1', 'post2'] // Array of all post IDs
}
}
Example:
// App.js
import React, { useState } from 'react';
// Before state normalization
const initialStateBefore = {
users: [
{ id: 1, name: 'Vijay', posts: [{ id: 1, title: 'Post 1' }] },
{ id: 2, name: 'Ankur', posts: [{ id: 2, title: 'Post 2' }] }
]
};
// After state normalization
const initialStateAfter = {
users: {
byId: {
1: { id: 1, name: 'Sourav', posts: [1] },
2: { id: 2, name: 'Vishal', posts: [2] }
},
allIds: [1, 2]
},
posts: {
byId: {
1: { id: 1, title: 'Post 1' },
2: { id: 2, title: 'Post 2' }
},
allIds: [1, 2]
}
};
const App = () => {
const [stateBefore] = useState(initialStateBefore);
const [stateAfter] = useState(initialStateAfter);
return (
<div>
<div>
<h2>Before State Normalization</h2>
<p>
In the initial state, the users and their
posts are stored together in a nested structure.
This can lead to duplication of data and
inefficient updates when the same user or
post is referenced in multiple places.
</p>
<div>
<h3>Users</h3>
<ul>
{stateBefore.users.map(user => (
<li key={user.id}>
{user.name}
<ul>
{user.posts.map(post => (
<li key={post.id}>{post.title}</li>
))}
</ul>
</li>
))}
</ul>
</div>
</div>
<div>
<h2>After State Normalization</h2>
<p>
After state normalization, the data is
structured in a flat format with entities
separated into individual objects.
This results in better performance,
easier data management, and reduced redundancy.
</p>
<div>
<h3>Users</h3>
<ul>
{stateAfter.users.allIds.map(userId => {
const user = stateAfter.users.byId[userId];
return (
<li key={user.id}>
{user.name}
<ul>
{user.posts.map(postId => {
const post = stateAfter.posts.byId[postId];
return <li key={post.id}>{post.title}</li>;
})}
</ul>
</li>
);
})}
</ul>
</div>
</div>
</div>
);
};
export default App;
Output:
Explain the Benefits of State Normalization in Redux
Redux is a predictable state container for JavaScript apps and offers a powerful solution for managing application states in complex web applications. One strategy that Redux uses is state normalization in which we can restructure state data to improve performance, maintainability, and scalability. In this article, we will discuss the benefits of state normalization in Redux and see why it’s a good practice for front-end developers.
Contact Us