You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using @lit/context and I often run into the limitation of wanting consumers to be able to update the provided value. Some basic use cases for this would be like a language switcher, dark/light theme toggle, or workspace selector (more advanced use cases later). In these, the component consuming the context should be able to modify the data and notify the provider so that other elements can update. Most other frameworks that have some form of context provide a mechanism for this.
I understand that context is not trying to become a state management tool. But I think a simple event to notify data change would greatly benefit frameworks building on top of it, while providing a much more elegant solution for simple things like the examples above and not requiring additional tools to keep necessary data in sync or greatly increasing the amount of code to implement it.
What I'm proposing is creating a ContextChangeEvent that consumers can emit with the new value so that the provider can update it. The solution I often use is implementing my own events that consumers emit and I have to add logic into the element providing it to update its value. I think that this is generic/boilerplate and that it should be built into context. Either elements can manually emit the event (providing a lot of possibilities for frameworks), or the ContextConsumer could trigger the event in the setter if previous value doesn't equal.
Functional Lit Examples
I have two examples that implement a ContextChangeEvent and the provider listens for events from it.
Table-View
In this Lit Playground Example, there is a user-list with two sub components table-view and column-picker. user-list provides a context for the data and another for which columns are visible. Here, I need my column-picker to update the context so that the table-view can rerender. I also want to support a filter-options component which would modify the query parameters used by the user-list but I left that out to keep it simple.
Timer Application
In this Lit Playground example, there is a Timer component that exposes Timer class instance. The timer class has logic for start/stop and the current timer count. There are two child components, one which displays the current time (only reads the context) and another which provides controls for the timer. I think more could be done to simplify this even more but I wanted an example that provides a class instance.
Alternatives Solutions
As mentioned above, I've previously just manually created events but this creates a lot of boiler plate code.
I've also experimented with providing an instance of @lit-labs/signals but it increases the complexity of the solution and with it being in stage 1 ran into a few issues.
I also tried including setter functions in the value provided but I dislike this as the real value is nested and in order to get it to update, the object needs to be cloned with this setters. This becomes even more complex if your providing a class as it needs to clone the class anytime it changes the value.
@provide({ context: columnContext })
accessor columns = {
value: [1,2,3],
setColumns: (columns) => {
this.columns = {
...this.columns, // This feels hacky and if its a class instance you lose this reference
value: columns
};
}
}
I have a lot more thoughts on this topic, but I'm trying to keep it as simple as possible. I went through a lot of ideas while trying and this to me is the simplest and most natural.
Lit adheres to this protocol so they will only implement it if its in the standard. Linking the ongoing discussion there: lit/lit#4908 (reply in thread)
edit - Lit is proposing the event name 'context-set-value'.
The text was updated successfully, but these errors were encountered:
joezappie
changed the title
Support a ContextChangeEvent to allow consumers to update the provided value
[Context] Support a ContextChangeEvent to allow consumers to update the provided value
Jan 31, 2025
One thing that came to mind is the ContextRequestEvent returns an unsubscribe callback. Maybe it would be cleaner to have a ContextGetSetterEvent which would return the set function which just provides a reference to provider.setValue and then the child element can cache that for later:
I'm using
@lit/context
and I often run into the limitation of wanting consumers to be able to update the provided value. Some basic use cases for this would be like a language switcher, dark/light theme toggle, or workspace selector (more advanced use cases later). In these, the component consuming the context should be able to modify the data and notify the provider so that other elements can update. Most other frameworks that have some form of context provide a mechanism for this.I understand that context is not trying to become a state management tool. But I think a simple event to notify data change would greatly benefit frameworks building on top of it, while providing a much more elegant solution for simple things like the examples above and not requiring additional tools to keep necessary data in sync or greatly increasing the amount of code to implement it.
What I'm proposing is creating a
ContextChangeEvent
that consumers can emit with the new value so that the provider can update it. The solution I often use is implementing my own events that consumers emit and I have to add logic into the element providing it to update its value. I think that this is generic/boilerplate and that it should be built into context. Either elements can manually emit the event (providing a lot of possibilities for frameworks), or theContextConsumer
could trigger the event in the setter if previous value doesn't equal.Functional Lit Examples
I have two examples that implement a
ContextChangeEvent
and the provider listens for events from it.Table-View
In this Lit Playground Example, there is a
user-list
with two sub componentstable-view
andcolumn-picker
.user-list
provides a context for the data and another for which columns are visible. Here, I need mycolumn-picker
to update the context so that thetable-view
can rerender. I also want to support afilter-options
component which would modify the query parameters used by theuser-list
but I left that out to keep it simple.Timer Application
In this Lit Playground example, there is a Timer component that exposes Timer class instance. The timer class has logic for start/stop and the current timer count. There are two child components, one which displays the current time (only reads the context) and another which provides controls for the timer. I think more could be done to simplify this even more but I wanted an example that provides a class instance.
Alternatives Solutions
@lit-labs/signals
but it increases the complexity of the solution and with it being in stage 1 ran into a few issues.I have a lot more thoughts on this topic, but I'm trying to keep it as simple as possible. I went through a lot of ideas while trying and this to me is the simplest and most natural.
Lit adheres to this protocol so they will only implement it if its in the standard. Linking the ongoing discussion there:
lit/lit#4908 (reply in thread)
edit - Lit is proposing the event name 'context-set-value'.
The text was updated successfully, but these errors were encountered: