Replies: 2 comments 1 reply
-
Also, if try to extend idea of selectors and fix it's current limitations, like allow subscribing to many sources, it may increase confusion even more, comparing it to native computeds. |
Beta Was this translation helpful? Give feedback.
-
Yeah, naming is hard. It did come from selected state. Hope you don't mind a short story. I hit this problem fairly often when working with Knockout and I was never really happy with the options. In the pre-proxy days when we wanted to do nested reactivity, we would use a utility like At my work we used a framework called Knockback which helped sort of automate this View Model wrapping of other nested models being able to assign other View Models. At a certain point, the performance of this was just too unwieldy. Like many reactive novices, I fell into the trap of too much granularity. I ended up writing a smaller/simpler library backout to replace it. Instead I focused on creating a single signal per model that trigger for any key. Tbe granularity wasn't worth it 90 percent of the time and since backbone already notified on nested updates I could just trigger the whole model. It was a good level of compromise. But that wasn't enough. To make it work nicely I added new bindings to allow us to map inside our views (https://github.com/ryansolid/component-register-ko). Since we only render once we could iterate over collection observables and then inline map those to new observable models. <ul data-bind="foreach: collection().models">
<li data-bind="use: ko.observableModel($data)">
<span data-bind="text: get('first_name')"></span>
</li>
</ul> I'm using backbone syntax in the view here because the whole model is subscribed. This removed the need to use In a lot of ways, our automatic proxies are just a re-imagined version of this. I didn't want to go back to using I knew back in 2014 I wanted to solve this in the framework but never did. If you look at Solid's history of commits in the JS Framework Benchmark I went through many iterations over the years. Even more, looking at Solid itself. Many different directive forms and transformer methods shipped with the framework. I had an after render hook at one point too. The concept of signal projection or data delegation. Eventually, I caved and just copied Adam's Surplus wrapping approach but I never was happy about that as I felt this needed a much more general solution. It was Recoil that woke me up. I was working on a JS Framework Benchmark for them early on but the performance wasn't optimized the way I had hoped it would be and I lamented why couldn't I just change the direction in this case. Have the signal notify specific subscriptions instead of all of them. Then I realized I could do exactly that. Not have the computation subscribe but have something else above call its update function directly. I could use this method for single and multi-select as long as we could control the comparison. The initial version was super limited it turned out since it wasn't re-usable but I was only thinking this simple case. We expanded it to handle notifying multiple at which point it came to my attention is was basically like projecting a signal per row. But honestly, this has been the extent of my thinking here. Is it more generalizable? Maybe. It is only really applicable to these sort of combining model projections I think. Is a better name |
Beta Was this translation helpful? Give feedback.
-
Few questions:
createSelector
outside of handling selected state ?This utility has pretty short description in the API and there is possibility that not everybody notice or understand it, despite having significant impact on performance.
If I'll try to build guide for it, based on its definition, it can be something:
then
createSelector
can provide performance benefits.But that feels quite heavy to apply in day-to-day practice, because of amount of conditions to apply it effectively.
One of the reasons for that could be that reactivity system don't have notion of "selectors". They have computeds for exact same purpose. That leads to another confusing question "why should I use selector instead of native computed/memo entities". Comparing it to vdom
shouldComponentUpdate
optimization, that one is quite general and simple to apply to many real use cases.If compare it to the spiritual predecessor
selectorFamily
from recoil, there are no such questions or confusing. Selectors are first class citizens in the system, going next after state atoms. There are no computeds and selectors are the only way to calculate memoized data. Also, there is no limitation on amount of dependencies,get
can be used as many times as needed and basically looks like teared down version of computeds, with explicit dependency wiring.If compare it to parameterized redux selectors, there is also no such confusion, they are first-class entity and they can listen to many other selectors.
The problem is also that there are no other similar operators or entities, to build some system from them. By idea it does "computation lifting" but question is can it be scaled and how to apply it ? If native computed graph is ineffective, maybe it'll worth to switch to lifting by default or to think how to apply it more widely ? Or there is a problem with computed graph that should be addressed in the first place, because users more likely going to use them by default so fix for this problem would give much greater benefits ?
Since this utility is included into the core package, there should be some way to fit it into the system.
Maybe name "selector" means "selected state" and can be confusing for new developers and might be better to change it ?
Would be happy to hear some thoughts or use cases.
Beta Was this translation helpful? Give feedback.
All reactions