-
Notifications
You must be signed in to change notification settings - Fork 9
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.