Dependent selectors

A dependent selector is a selector that computes a result from one or more selectors. This functionality is inspired by reselect. Like reselect, you simply need to pass two or more functions to createSelector, like createSelector(...selectors, resultsFunc). The last function is treated as a "results function" while every other function is treated as a "dependent selector". The values from each dependent selector become the arguments for the results function.

A results function receives the value from each dependent selector, like resultsFunc(...results). You can see it in action below to make things more clear.

Unlike path selectors, dependent selectors are memoized using memoizeSelector. This means that the value returned from the results function is cached until the state changes. This can improve performance in cases where state seldom changes or when the dependent selectors are difficult to compute.

For convenience, createSelector supports both functions and path strings. This enables you to easily create robust selectors on-the-fly if needed. Under the hood, each selector is passed thru createStateSelector in order to transform path strings into functional selectors.

Notice in the example below that you can use a mix of selectors and paths for your dependent selectors. The result of each selector is pass as an arg to the results function. You can see below that the results function receives apples, oranges, peas, carrots, one argument for each selector. Also notice how a path, 'veggies.peas' is used to select peas and how an inline function is used to select carrots.

import { createSelector } '@comfy/redux-selectors'

export const selectApples = createSelector('fruit.apples')
export const selectOranges = createSelector('fruit.oranges')

// a dependent selector
export const selectTotal = createSelector(
  // use existing selectors
  selectApples,
  selectOranges,

  // or create new selectors
  'veggies.peas',
  state => state.veggies.carrots,

  // results function
  (apples, oranges, peas, carrots) => apples + oranges + peas + carrots
)

// ---

const state = {
  fruit: { apples: 1, oranges: 2 },
  veggies: { peas: 3, carrots: 4 }
}

selectTotal(state) // => 10

Using get and reselect instead

Comfy redux-selectors isn't doing anything particularly special. You can accomplish the same result with reselect. Compare the following example that uses reselect and get. Just like redux-selectors, reselect will memoize your dependent selector.

import { createSelector as createReselectSelector } 'reselect' // <-- use reselect if you want
import get from 'lodash.get'

export const selectApples = state => get(state, 'fruit.apples')
export const selectOranges = state => get(state, 'fruit.oranges')

// a dependent selector
export const selectTotal = createReselectSelector(
  // use existing selectors
  selectApples,
  selectOranges,

  // or create new selectors
  state => get(state, 'veggies.peas'),
  state => state.veggies.carrots,

  // results function
  (apples, oranges, peas, carrots) => apples + oranges + peas + carrots
)

// ---

const state = {
  fruit: { apples: 1, oranges: 2 },
  veggies: { peas: 3, carrots: 4 }
}

selectTotal(state) // => 10

Next: Configurable selectors

results matching ""

    powered by

    No results matching ""