Redux Selectors
What are they and why should I use them?
2016-09-15
When I first started using Redux, I didn’t understand selectors. They seemed like a completely unnecessary intermediate layer that just slowed me down. I learned later, however, that they’re actually there to speed me up.
Redux tip: export selectors with related reducers. They let you decouple views and action creators from state shape
At a fundamental level, the driving principle behind selectors is loose coupling. It helps to consider each key-space of your Redux store to be an ‘object’ and the properties it contains to be ‘methods’ which we want to access. Given this definition, The Law of Demeter can then be applied. However you want to define it, Selectors allow us to decouple the components of our Redux store, both from each other and from their consumers.
Why is this a good thing? The code following this pattern will be more maintainable and less likely to break. Tests can be primarily focused on limited access patterns to very specific components and you don’t have to worry about reference sprawl when changing the structure of your Redux store.
Imagine that you have implemented a simple website that needs to track info about the current user. You don’t need to worry too much about the perfect layout of your data, so you just put the user’s information in a record stored in the ‘current_user’ key of the rood reducer.
|
|
Next, imagine that you add support for comments, live chat, forums, or leaderboards. Now you need to keep track of multiple different user records and look them up by ID. You decide that you should store a mapping of User records in your store (probably using normalizr) and it makes sense to include the current_user in that list. You don’t really want to keep a duplicate record around that you have to keep synchronized at the ‘current_user’ key – you decide to just store the current user’s ID.
|
|
If you’ve been accessing the Redux store directly, you may have to modify twenty different call sites and rework the code at each location to retrieve the ID and then use that ID to resolve the correct user. With selectors, you’d only have to modify a single function.
As an added bonus, selectors at each layer of your store offer great injection points to use libraries like reselect, trigger asynchronous refreshing behavior, and merge, transform, or aggregate stored data into more digestible forms. Decoupling your data can be just as useful as decoupling your code. You’ll find increased modularity means easier testing and more reusable code.
No one starts with the perfect design. A Next Level Developer stays agile to stay ahead, because they know that requirements always change.