abrarisme abrarisme - 2 months ago 17
React JSX Question

How do I access Redux items using selectors after I've normalized my store?

I'm a bit confused on how I'm supposed to use selectors after I've normalized my Redux store.

I have the following setup for my store:

const DEFAULT_STATE = {
allId: [],
locations: {}
};


With the following for my reducer:

handleActions({
['UPDATE']: (state, action) => {
let newID = state.allId.length;

const allId = [...state.allId, newID];
const locations = {
...state.locations,
[newID]: action.payload
};
return {allId, locations};
}
}),
...


I figured I would want something like this for my component:

function mapStateToProps(state) {
return {
share: callMySelector(state)
};
}


But I don't see how my selector would do anything except return the
location
associated with the most recent ID. I'm thinking that normalizing is also not that great here - because I wouldn't end up searching by ID in a regular case.

Answer Source

The power of selectors is that it moves filtering logic away from the component consuming the data, and away from the actions/reducer into reusable functions. You mentioned getting the most recent location. From the update logic in the reducer, we'd just make a selector that grabs the last item.

function selectLatestLocation(state) {
  const latestId = state.allIds[state.allIds.length - 1];

  return state.locations[latestId];
}

This assumes the location data is structured with the location id as the key.

 {
   1: { id: 1, name: "USA" },
   2: { id: 2, name: "Europe" }
 }

In this case, normalizing the data isn't doing much. But let's say requirements change, and now we only want Europe locations. We could have another state property called europeIds that contains all Europe location ids.

function selectEuropeLocations(state) {
   return state.europeIds.map(id => state.locations[id]);
}

Using selectors with normalized Redux state make it really easy to change how data is filtered. Now like you said, some cases might not need to be normalized. It is really up to the project, and what is being accomplished. But, it's definitely worth it for data that needs to be memoized, or filtered in different ways!