-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Selector dependencies using this
#14
Comments
It would also be interesting to see if there would be a good way to apply
Without a final syntax for decorators, I'm not sure this is feasible. But even if we had a good way to apply these annotations,
|
This does feel much more intuitive. One issue I'd like to raise in terms of API design is first-class support for |
Yep, I definitely want memoization to be available. But our past experience with Reselect was that it was pretty awkward to apply -- lots of boilerplate. Don't get me wrong, we'd still use it if we knew we had a selector that was killing performance, but I think it's best applied sparingly. I'd like to try to provide that functionality with a cleaner API, whether that uses Reselect under the hood, or some other memoization implementation. I also find MobX to be pretty fascinating, and everything I've read says it's pretty robust. Maybe it would be possible to use its observables and computed values directly to implement this. If we did use Reselect though, it would probably be important to make it opt-in, and to expose its configurability. |
When you were using reselect before what kind of boilerplate were you running into? I've used it extensively (in a more vanilla redux setup) and have never run into anything that was more complex than a function call -- curious how you were using it? Something like... import { createSelector } from 'reselect'
const nameSelector = state => state.name
const ageSelector = state => state.age
const mapStateToProps = createSelector(nameSelector, ageSelector,
(name, age) => {
return name + ' ' + age
}
)
// Or
const mapStateToProps = createSelector(
state => state.name,
state => state.age,
(name, age) => {
return name + ' ' + age
}
) Now that I've typed it out I can definitely see how this could be a little boilerplate heavy in an app like Prediction, but I can also see it being seamlessly (and simply) incorporated behind RRC. One other thing to possibly look into is Will check out MobX! I've heard of it but have never dove in. |
Yeah, exactly. With the probably several dozen selectors we have over there, So, we tried doing without memoization and didn't notice a difference at all. I haven't collected hard data on it, but I'd guess that calling every selector (as happens on every state change in RRC) doesn't actually take more than maybe a couple milliseconds. In your example, at the two function calls have to happen to determine whether to concatenate some strings, combined with the internal machinery of Reselect. This could actually be a net loss versus simply concatenating the strings every time. A lot of our selectors actually are pretty much like this. My concern with Reselect is that it's designed to work with selectors designed as functions over the state. In a paradigm where selectors access the state on RRC today computes all the selectors eagerly every store change. This is wasteful in the case that only some selectors are used, or in the case that most of the selector outputs didn't change -- probably the norm. Naively, this proposal would lead to selectors that are recalculated on demand. But this is wasteful when one selector is accessed many times by other selectors, components or controller methods. We could avoid these problems by only recomputing a selector when its inputs change. (We could go even further and trade memory for time by caching some number of selector input * output combinations.) But this comes at a certain cost of needing to specify exactly what the dependencies of each selector is. I haven't figured yet out how MobX |
I looked into how MobX If I understand it, the TLDR of it is that computed properties don't statically track their depedencies (i.e. I'm very intrigued by this. Since
RRC would simply instantiate your selector class one time and |
any news? :) |
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:
The functional composition works, but it's also pretty noisy. A better API might be:
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.
The text was updated successfully, but these errors were encountered: