-
Notifications
You must be signed in to change notification settings - Fork 293
Selectors
If actions
are the entry points, selectors are the exit. After dispatch
ing 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),
})
test('getList', () => {
expect(getList({ list: [1, 2, 3] })).toEqual([1, 2, 3])
})
Special thanks to @kybarg and @protoEvangelion for helping to write this Wiki. Please, feel free to edit/create pages if you think it might be useful (also, see #33)