Skip to content
Diego Haz edited this page May 19, 2017 · 7 revisions

If actions are the entry points, selectors are the exit. After dispatching an action, the application can use selectors to get the resulting data from the store after reducers and sagas have done something with it.

Basically, you can use selectors to get some part of the current state. Here's a basic usage:

// src/store/selectors.js
export const getResourceList = state => state.resource.list
// src/containers/ResourceList.js
import { getResourceList } from 'store/selectors'

const mapStateToProps = state => ({
  list: getResourceList(state),
})

As you may have noticed, the selector above is defined outside of the resource module directory. That's because the redux state tree is one single javascript plain object with all modules inside, like this:

{
  resource: {
    list: [],
  },
  status: {
    loading: [],
    error: [],
  },
  ...
}

Modules themselves don't know their property names (resource, status) on the root state because it's defined on src/store/reducer.js.

The solution is mapping all modules selectors in src/store/selectors.js passing the respective property names to them, while, inside modules, we can create selectors based only on the module's state structure:

// src/store/resource/selectors.js
export const getList = state => state.list
// src/store/selectors.js
// The real file has a more nifty algorithm
import { getList } from './resource/selectors'
export const fromResource = {
  getList: state => getList(state.resource)
}
// src/containers/ResourceList.js
import { fromResource } from 'store/selectors'

const mapStateToProps = state => ({
  list: fromResource.getList(state),
})

Unit testing selectors

test('getList', () => {
  expect(getList({ list: [1, 2, 3] })).toEqual([1, 2, 3])
})
Clone this wiki locally