Feature request: Lens like utility for stores #944
Replies: 8 comments
-
Actually just the focus on the setter side is more handy to have, because you already get the getter for free from Rough sketch:
Then the returned setter gets passed down to the ui component in the tab through its properties. Then the inner tab ui can operate on its own state while being unaware of the outer application state, and the outer application can be unaware of the state changes to the inner tab ui (encapsulation). So that the parts responsible for a piece of state, manage that state. |
Beta Was this translation helpful? Give feedback.
-
I am on board. I think this is a great idea. I've had this conversation a couple of times. And you are right setters are key since the whole reactive system has the ability to easily pull out the getter side. The implementation is what I've mostly been trying to decide given Solid's internally mutable nature. However it's the path we care about rather than the reference. But the key to not killing performance is not to resolve the path every time you set. Otherwise one could wrap this themselves pretty easily. Something like this (untested, literally just thinking out loud): function getPath(path, getState) {
return () => {
let state = getState();
while(segment = path.shift()) {
state = state[segment]
}
return state;
}
}
function createLensLikeThing(path, [getState, setState]) {
return [getPath(getState, path), (...args) => setState(...path, ...args)]
} But I feel we can leverage our internals more. The problem is we are still going through all the iteration. Maybe it's impossible to avoid given it's the path we care about rather than the reference. Somebody was wondering about a solution for trees and I pointed them to |
Beta Was this translation helpful? Give feedback.
-
Need to partially resolve a path somehow, then resolve the remainder later. |
Beta Was this translation helpful? Give feedback.
-
Yeah the problem is if someone blows away the path higher up you could be holding a reference to an object that is no longer connected to the tree. So the only thing I can think of is track that part of the path in a memo and use that to get new getter/setters.. Then it only recalculates when the root changes and otherwise shortcuts the work on each nested set. That will take accessing some of the internals and I feel I can build that in but I need to spend some time playing around with it. |
Beta Was this translation helpful? Give feedback.
-
Maybe help https://github.com/akheron/optics-ts |
Beta Was this translation helpful? Give feedback.
-
I like this idea and given the close similarities between solidjs signals and klyva atoms (which uses optics-ts and works reasonably well for react, though not widely in usage and limited in documentation & community) I think this is a direction worth pursuing. I agree 100% though that a rough spot for optics-ts (at least in the context of klyva atoms) that I experienced was the handling of writable atoms within optional values/prisms where the path was blown up. But even if anything along the path is not allowed to be undefined/optional for the atom to be writable, it would still be quite useful for many cases. I believe there’s possibly also some challenges around setters for substate when setting on atoms with discriminated unions, but not 100% sure about that. |
Beta Was this translation helpful? Give feedback.
-
I'm moving any new feature ideas to discussions to better facilitate and keep issues to things that need immediate attention, are a major milestone, or a have a timeline of attacking. |
Beta Was this translation helpful? Give feedback.
-
I started a draft PR in |
Beta Was this translation helpful? Give feedback.
-
Say our application state holds a collection of states of things in the tabs of the application. It can be handy to have a Lens to focus on a subset of the state in order to provide a store for use by the UI in the tabs state. So that rhe end-user does not need to alway push state changes to top level (under the hood the state still reaches the top, it is just hidden boiler plate).
Make like:
[getProjState, setProjState] = createLens(path, [getAppState, setAppState]);
In the example above the created setProjState functions calls setAppState inside with a bit extra prepended to its path.
Beta Was this translation helpful? Give feedback.
All reactions