Description
Right now, RRC provides no real help for the selector story. In our use case at Artsy, we have a great deal of selectors, which depend on the state and on each other. However, writing these selectors as functions from state to a derived value is a bit awkward, composing them is even more so, and using something like reselect
for memoization is so awkward that we don't even bother.
In the example, we have:
import { PropTypes } from 'react'
export const selectedReddit = state => state.selectedReddit
selectedReddit.propType = PropTypes.string.isRequired
export const postsByReddit = state => state.postsByReddit
postsByReddit.propType = PropTypes.object.isRequired
export const posts = state => {
const p = state.postsByReddit[selectedReddit(state)]
return p && p.items ? p.items : []
}
posts.propType = PropTypes.array.isRequired
export const isFetching = state => {
const posts = state.postsByReddit[selectedReddit(state)]
return posts ? posts.isFetching : true
}
isFetching.propType = PropTypes.bool.isRequired
export const lastUpdated = state => {
const posts = state.postsByReddit[selectedReddit(state)]
return posts && posts.lastUpdated
}
lastUpdated.propType = PropTypes.number
The functional composition works, but it's also pretty noisy. A better API might be:
export class Selectors {
get posts() {
const p = this.postsByReddit[this.selectedReddit]
return p && p.items ? p.items : []
}
get isFetching() {
const posts = this.postsByReddit[this.selectedReddit]
return posts ? posts.isFetching : true
}
get lastUpdated() {
const posts = this.postsByReddit[this.selectedReddit]
return posts && posts.lastUpdated
}
}
Selectors.propTypes = {
selectedReddit: PropTypes.string.isRequired,
postsByReddit: PropTypes.object.isRequired,
posts: PropTypes.array.isRequired,
isFetching: PropTypes.bool.isRequired,
lastUpdated: PropTypes.number
};
This feels much more direct and intuitive. Library magic would make sure that the Redux state is accessible via this
.
Selectors would also become lazy, instead of eagerly computed. It may also be possible to rely on said library magic to opt selectors into memoization.