Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redux normalized state: byId and allIds pattern

Tags:

reactjs

redux

I am going through the documented pattern for structuring application state:

https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape

There one sees the following suggested way of maintaining the posts of a hypothetical blogging application:

 posts : {
    byId : {
        "post1" : {
            id : "post1",
            author : "user1",
            body : "......",
            comments : ["comment1", "comment2"]
        },
        "post2" : {
            id : "post2",
            author : "user2",
            body : "......",
            comments : ["comment3", "comment4", "comment5"]
        }
    },
    allIds : ["post1", "post2"]
}

It is not at all clear to me what is the benefit of maintaining the allIds field on that state. Doesn't the following data structure contain the exact same information?:

posts : {
        "post1" : {
            id : "post1",
            author : "user1",
            body : "......",
            comments : ["comment1", "comment2"]
        },
        "post2" : {
            id : "post2",
            author : "user2",
            body : "......",
            comments : ["comment3", "comment4", "comment5"]
        }
}

The way I see it, the first approach (i.e. the officially suggested one) has redundant information which is normally seen as a defect. The only benefit of the first approach that I see is in case we are using the byId property to cache some posts in advance. I am sure the official redux documentation has valid reasons for suggesting this pattern. I have used Redux in a few React apps but nothing too complex so I must be clearly failing to see something.

like image 974
Marcus Junius Brutus Avatar asked May 22 '20 16:05

Marcus Junius Brutus


People also ask

Should Redux state be normalized?

As it turns out, having connected parent components simply pass item IDs to connected children is a good pattern for optimizing UI performance in a React Redux application, so keeping state normalized plays a key role in improving performance.

Why is it recommended to normalize the state?

A normalized state is a way to store (organize) data. With this way each entity type will have its own place in the store, so that there is only a single point of truth. This practice is the recommended way to organize data in a Redux application as you can read in the Redux recipes.

How do I optimize Redux performance?

For maximum rendering performance in a React application, state should be stored in a normalized shape, many individual components should be connected to the store instead of just a few, and connected list components should pass item IDs to their connected child list items (allowing the list items to look up their own ...

How is state changed in Redux?

The state can only be changed by emitting an action. The state tree is never mutated directly instead you use pure functions called reducers. A reducer takes the current state tree and an action as arguments and returns the resulting state tree.


1 Answers

The allIds field has a couple benefits:

  • It provides a consistent array reference for "all IDs", whereas something like Object.keys(state.posts) creates a new array every time
  • It can act as a default sort order for all the items, whether it be based on insertion order or something else.

Our official Redux Toolkit package now has a new createEntityAdapter API that implements the logic for managing this kind of normalized state shape, which it organizes as {ids: [], entities: {} }. It specifically implements the ability to keep the ids array in sorted order, and ensures the ids array only changes when items are added, removed, or the sort order changes.

You might also want to read through Advanced Redux Entity Normalization, which has further thoughts on the use of ID arrays to indicate filtering and sort order.

like image 159
markerikson Avatar answered Oct 13 '22 04:10

markerikson