Replies: 2 comments 3 replies
-
Realised I didn't give a vanilla example without the web component usage: const state = proxy({ value: 'Example' });
const r = reaction(() => {
console.log(`The value is updated!`);
});
// track some value
r.track(() => {
reference.value; // read a value from the proxy to track it
}) This approach lets you make side effects very easily. Within class ValtioWatchingElement extends constructor {
private valtioReaction?: Reaction;
public connectedCallback(): void {
super.connectedCallback();
// create a reaction that will invoke the `requestUpdate` function when tracked
// data changes, this will drive the update lifecycle of the element
this.valtioReaction = reaction(() => this.requestUpdate());
if (this.hasUpdated) this.requestUpdate();
}
public disconnectedCallback(): void {
super.disconnectedCallback();
if (this.valtioReaction) {
// cleanup when the component is disconnected
this.valtioReaction.dispose();
this.valtioReaction = undefined;
}
}
protected update(changedProperties: PropertyValues): void {
// use the `update` function to track proxies used in the components render
this.valtioReaction.track(super.update.bind(this, changedProperties));
}
}; Users can then mixin this implementation onto any web component to make it 'valtio aware' without changing its internal render templates. |
Beta Was this translation helpful? Give feedback.
-
The philosophy of valtio is to make things simple not only in usage but also in implementation. One big design decision is its core (vanilla.ts) doesn't handle What we currently do for fine-grained reactivity is double proxies for So, in this mental model, the reaction feature should be a third-party library like We could still explore the possibility of |
Beta Was this translation helpful? Give feedback.
-
I've been trying to add valtio to my workflow within lit web components in a similar manner to my usage of mobx with the lit-mobx library. i.e. transparently without the need to manually subscribe, or use the watch get function.
For mobx this was achieved using their Reaction pattern, which allows us to have a data tracking function (in this case the lit update lifecycle method which is invoked just before render and is used to track the variables to respond to, and then an effect method which we use to request an update to the components. This split between tracking / effect allows for a more fine grained control of behavior.
I've implemented this by refactoring the watch method a little bit, and adding a basic automatic tracking of accessed proxies via the proxy get implementation. This seems to work pretty well, allowing for a very natural usage of properties without having to wrap each proxy access in a get call as we do with watch today. This makes adding observability via valtio to a lit element very natural since we can make it aware of observable properties through a mixin without having to rewrite the internal render functions.
As an example of usage within a valtio adapted lit element base class:
We can see how this element could simply be based on regular LitElement, and will update when reference equality of the counter property changes, or could be upgraded to support a Valtio proxy on its Counter property simply by mixing in the lit-valtio library, with WebComponents this can be done by just subclassing the default implementation of the element. This approach has proved pretty popular with the web components community since it allows you to build your components very agnostic of the state library.
Would be interested in folks thoughts on the utility of the
reaction
approach within valtio.Beta Was this translation helpful? Give feedback.
All reactions