When working on modern frontend applications, especially those with dynamic and interconnected data (like posts, comments, and users), managing state can quickly become complicated. APIs often return deeply nested data, and performing updates, deletions, or additions on such structures can feel like navigating a maze.
For instance, imagine an app like Facebook or Reddit. Each post has comments, each comment has users, and each user might appear in multiple comments or posts. If you try to edit or delete a user, you’d have to find and update that user’s data in every place they appear. This approach quickly becomes unmanageable.
That’s where data normalization comes in.
What Is Data Normalization?
Normalization means organizing your data so that each piece of information exists in exactly one place.
Instead of keeping a deeply nested structure, you store data in flat, relational objects, similar to how relational databases work.
For example:
Instead of keeping users nested inside comments, which are nested inside posts,
You separate them into different collections (posts, comments, users),
Then you use IDs to link them together.
This makes it much easier to update, delete, or add new data consistently.
The Problem: Nested Data Example
Let’s say our API returns this data for posts:
const posts = [
{
id: 1,
title: "Understanding React",
comments: [
{
id: 101,
text: "Great post!",
user: {
id: 1001,
name: "Abdallah Ahmed",
},
},
{
id: 102,
text: "Thanks for sharing",
user: {
id: 1002,
name: "Sara Ali",
},
},
],
},
];
Now, imagine you need to update the user’s name (for example, Abdallah changes his name).
You’ll have to:
Loop through each post,
Then through each comment,
Then find the user,
And finally update the name.
That’s a lot of unnecessary traversal — and if the same user appears in multiple posts or comments, you’ll need to update every occurrence manually.
This leads to data duplication and inconsistent states.
The Solution: Normalized Data Structure
After normalization, we can represent the same data like this:
const normalizedData = {
posts: {
1: { id: 1, title: "Understanding React", comments: [101, 102] },
},
comments: {
101: { id: 101, text: "Great post!", user: 1001 },
102: { id: 102, text: "Thanks for sharing", user: 1002 },
},
users: {
1001: { id: 1001, name: "Abdallah Ahmed" },
1002: { id: 1002, name: "Sara Ali" },
},
};
Now, all entities (posts, comments, users) are stored separately and referenced by IDs.
Example Operations
- Updating a User’s Name
Before normalization:
// Update user's name (nested approach)
posts.forEach(post => {
post.comments.forEach(comment => {
if (comment.user.id === 1001) {
comment.user.name = "Abdallah A.";
}
});
});
After normalization:
// Simple and efficient
normalizedData.users[1001].name = "Abdallah A.";
Only one update is needed — and all parts of your app that reference this user will automatically get the updated name.
- Deleting a Comment
Before normalization:
// Remove comment 101
posts[0].comments = posts[0].comments.filter(c => c.id !== 101);
After normalization:
// Delete from comment list
delete normalizedData.comments[101];
// Remove reference from the post
normalizedData.posts[1].comments = normalizedData.posts[1].comments.filter(
id => id !== 101
);
Clean, simple, and consistent — no deeply nested loops.
- Adding a New Comment
Before normalization:
const newComment = {
id: 103,
text: "Very helpful!",
user: { id: 1003, name: "Ali Mohamed" },
};
posts[0].comments.push(newComment);
After normalization:
normalizedData.users[1003] = { id: 1003, name: "Ali Mohamed" };
normalizedData.comments[103] = { id: 103, text: "Very helpful!", user: 1003 };
normalizedData.posts[1].comments.push(103);
The data remains structured, and each entity is tracked in one place.
Benefits of Normalization
✅ Easier updates – Change data in one place, not everywhere.
✅ Less duplication – Each entity exists only once.
✅ Simplified logic – Easier to add, remove, or merge entities.
✅ Improved performance – Less re-rendering and simpler lookups in UI frameworks like React.
✅ Scalable structure – Works great as your app and data grow in complexity.
Top comments (0)