SmallTown NE
SmallTown NE

Reputation: 613

About normalize in redux real-world example

In the example's src(UserPage.js):

  const mapStateToProps = (state, ownProps) => {
  // We need to lower case the login due to the way GitHub's API behaves.
  // Have a look at ../middleware/api.js for more details.
  const login = ownProps.params.login.toLowerCase()

  const {
    pagination: { starredByUser },
    entities: { users, repos }
  } = state

  const starredPagination = starredByUser[login] || { ids: [] }
  const starredRepos = starredPagination.ids.map(id => repos[id])
  const starredRepoOwners = starredRepos.map(repo => users[repo.owner])

  return {
    login,
    starredRepos,
    starredRepoOwners,
    starredPagination,
    user: users[login]
  }
}

I notice that there is many templates like xxx.ids.map(id => someEntities[id]),I am not sure why use this pattern to work.IMO,I would use something like import { map } from 'lodash'; someList && map(someList, item => {...}) in the container component and just pass the entities in the mapStateToProps.

So,could someone explains it's purpose?Thanks.

Upvotes: 1

Views: 533

Answers (1)

markerikson
markerikson

Reputation: 67539

The standard suggestion for normalizing data in Redux is to store data items in an object, with IDs as the keys and the items as the values. However, an object doesn't have an inherent order to it. (Technically, the order of iteration for object keys should be consistent, but it's a bad practice to rely on that as the sole means of ordering.)

Because of that, it's also standard to store an array of just the IDs as well. A typical example might look like:

{
    byId : {
        qwerty : { },
        abcd : { },
        aj42913 : { }    
    },
    items : ["qwerty", "aj42913", "abcd"],
    sorted : ["abcd", "aj42913", "qwerty"],
    selected : ["qwerty", "abcd"]
}

In this example, items contains all item IDs, probably in the order they were insert. sorted contains the IDs in some sort of sorted order, while selected contains a subset of the IDs.

This allows the items themselves to only be stored once, while multiple representations of those items can be saved using various arrays of IDs.

From there, you can pull together a list of the actual items by mapping over whatever array of IDs you care about, and retrieving the items by their IDs.

So, ultimately the answer is that relying just on the keys of the byId object doesn't give you any kind of ordering, and doesn't allow defining subsets of the data.

Upvotes: 2

Related Questions