solid-primitives
solid-primitives copied to clipboard
Add `createLens` primitive
Utilities for working with nested reactivity in a modular way.
-
createLens
- Given a path within a Store object, return a derived or "focused" getter and setter pair. -
createFocusedGetter
- The first half of the lens tuple; a derived signal using path syntax on an object. -
createFocusedSetter
- The second half of the lens tuple; a Setter for a specific path within a Store.
How to use it
// Start with an ordinary SolidJS Store
const storeTuple = createStore([
{ myString: 'first' }
])
// Create a lens to focus on one particular item in the Store.
// Any valid path accepted by `setStore` works here!
const [firstString, setFirstString] = createLens(storeTuple, 0, myString)
// Setters and Getters work just like ordinary Signals
setFirstString("woohoo") // equivalent to `setStore(0, "myString", "woohoo")
console.log(firstString()) // "woohoo"
Motivation
1. Separation of Concerns
Components can receive scoped Setters for only the parts of state they need
access to, rather than needing a top-level setStore
function.
2. Type-safety
Essentially, we are just partially applying a setStore
function with an initial path, and returning a function that will apply the
remainder of the path. It is just syntactic sugar, and under the hood
everything is using calls to native Store functionality.
The same approach can already be used by the Setter returned by createStore
. However,
Typescript users will find it hard to maintain type-safety for the arguments
passed to a "derived"/partially-applied Setter. The type definitions for SetStoreFunction
are...
daunting.
The lenses
package alleviates this friction by providing both StorePath<T>
and EvaluatePath<T, P>
generic type helpers.
3. Shared path syntax between Getters and Setters
The path syntax defined in Solid Stores is incredibly expressive and powerful.
By introducing createScopedGetter
, the same syntax can be also be used to
access Store values as derived Signals. This is particularly relevant to
child components which may both display and modify items from a Store
collection.
Closes #453