If you’ve ever had to deal with derived data in redux, you know those can be kind of a pain once your state is normalized - so you start using reselect.

This leads to some code like this (example adapted from the official reselect docs):

// in your selectors...

import { createSelector } from 'reselect';

const shopItemsSelector = state => state.shop.items;
const taxPercentSelector = state => state.shop.taxPercent;

const subtotalSelector = createSelector(
  shopItemsSelector,
  items => items.reduce((acc, item) => acc + item.value, 0)
)

const makeTaxSelector = () => createSelector(
  [subtotalSelector, taxPercentSelector],
  (subtotal, taxPercent) => subtotal * (taxPercent / 100),
);

// and in your container...

const makeMapStateToProps = () => {
  const taxSelector = makeTaxSelector()
  const mapStateToProps = (state, props) => ({
    tax: taxSelector(state, props),
  });
  return mapStateToProps;
}

The problem there is that once you call taxSelector, you hava an implicit dependency on how your state is structured - over time, specially if you start creating generic reducers/selectors, this causes some problems both when documenting and when trying to reuse the code.

For instance, a coworker recently realized we were duplicating selector code because in some components our taxPercent equivalent was indeed in the state, but in others it was in a prop - imagine for instance you wanted to calculate both domestic and international tax rates. Might also be a good use for re-reselect, buts a whole different topic.

So we made a somewhat subtle change in how we write our memoized selectors, and started injecting selector dependencies (but keeping the state as a default):

const shopItemsFromState = state => state.shop.items;
const taxPercentFromState = state => state.shop.taxPercent;

const subtotalFromState = createSelector(
  shopItemsFromState,
  items => items.reduce((acc, item) => acc + item.value, 0)
)

const makeTaxSelector = 
  (subtotalSelector = subtotalFromState,
   taxPercentSelector = taxPercentSelector) => createSelector(
    [subtotalSelector, taxPercentSelector],
    (subtotal, taxPercent) => subtotal * (taxPercent / 100),
);

We also created some “utility” selectors to ease the use on the containers:

const constSelector = value => () => value;
const propSelector = prop => (state, props) => props[prop];

So when we are testing a selector, we now do:

  const taxSelector = makeTaxSelector(constSelector(42), constSelector(10));
  expect(taxSelector()).to.equal(4.2);

Now our selector unit tests don’t break when we modify state structure, and we get to reuse code in more containers that do the same thing in multiple places!