Search code examples
reduxreact-reduxngrx

Redux - Async logic in Normalized State


Found a lot of information on Normalizing state in Redux, but still not clear on the flow when connecting to Backend endpoints.

If anyone is kind enough to reply to this long post, I'd really appreciate it. Please, share your knowledge or references on how to handle the async logic for normalized state.

Let's take an example of Normalized state from official documentation: (shortened version for readability)

{
posts : {
    byId : {
        "post1" : {
            id : "post1",
            author : "user1",
            body : "......",
            comments : ["comment1", "comment2"]
        }
    },
    allIds : ["post1"]
},
comments : {
    byId : {
        "comment1" : {
            id : "comment1",
            author : "user2",
            comment : ".....",
        },
        "comment2" : {
            id : "comment2",
            author : "user3",
            comment : ".....",
        }
    },
    allIds : ["comment1", "comment2", "comment3", "comment4", "comment5"]
},
users : {
    byId : {
        "user1" : {
            username : "user1",
            name : "User 1",
        }
    },
    allIds : ["user1"]
}

}

Questions:

  1. Does it mean that I have to fetch ALL existing comments from server before I am able to query needed comments from redux state?

OR

Should I only fetch the needed comments using the array of IDs(post.comments) from the server when displaying specific post, in this case would I replace all comment entities with the ones I get from the server?

  1. When is this example structure applicable? is it still considered a normalized? How would I handle async logic here?

     entities: {
         authors : { byId : {}, allIds : [] },
         books : { byId : {}, allIds : [] },
         authorBook : {
             byId : {
                 1 : {
                     id : 1,
                     authorId : 5,
                     bookId : 22
                 },
                 2 : {
                     id : 2,
                     authorId : 5,
                     bookId : 15,
                 },
                 3 : {
                     id : 3,
                     authorId : 42,
                     bookId : 12
                 }
             },
             allIds : [1, 2, 3]
    
         }
    

Useful answers on the topic: markerikson

Helpful documentation on the topic: Async logic, Normalizing state, Updating Normalized state


Solution

  • Hiya :) "Normalized" does not mean "I have fetched every single possible value from the server first". It just means that the entries you have fetched are being stored in that lookup table keyed by item IDs. You could fetch some posts and their comments, load them into those normalized lookup tables, fetch some more and add them, etc. (In fact, that's why Redux Toolkit's createEntityAdapter API provides update functions to add/insert/update more items into an existing normalized lookup table.)

    So, one possible usage scenario might be:

    • Fetch one page's worth of posts, insert into the normalized posts state
    • User opens a post, fetch that posts's comments and insert into the normalized comments state
    • Repeat those as necessary