Closed sasacocic closed 1 year ago
There are two parts for contexts to work: A "provider" somewhere up in the virtual dom tree, and the "consumers" below it.
When a provider wants to make some type of context, let's say a Theme
, a value theme: Theme
accessible to some of its children, he should render
<ContextProvider<Theme> context={theme}>
{children_with_consumers}
</ContextProvider<Theme>>
To update the provided value, the provider needs to re-render and pass the updated value as the new context
property of <ContextProvider<Theme> context={theme}>
. This will then trigger all subscribers down below. I think at this point the current page is inaccurate saying
The children are re-rendered when the context changes.
instead of
The subscribed children are notified when the context changes.
Note that children_with_consumers
does most often not change in this re-render, so not all children are re-rendered. But it is technically allowed to mix these two updates and when new, changed, children_with_consumers
are rendered, this will re-render all of those (shallowly, with the usual vdom diffing) too. I'm a bit split if that point is worth mentioning, since it's more-or-less the only sane and also expected behavior.
The struct consumer calls ctx.link().context::<Theme>(cb)
and has to provide a callback cb
that will be called when the context changes (the trigger). This callback is called with the updated context value and is expected to return a Message
that is sent to the struct component. The call to context
returns the current/initial, immediate context value (as the provider already exists and has a definite provided value) and a ContextHandle
. This second struct models the interest in receiving updates through the callback. Dropping it (e.g. as part of the component being destroyed), will unsubscribe from receiving updates when the context updates.
The struct example (in the v0.19 docs) slightly misused this API in the guise of simplification. The context
is gotten directly in fn view
, which always uses the most up-to-date context either way, which does more work and doesn't receive updates - passing Callback::noop()
. This will fail to re-render the component when the the theme changes.
In function components, use_context
is similar, except its use will always re-render instead of sending a message, and the updated context will be picked up during that render, so no callback here. An example is missing and should also show off using the Theme
context. I.e. the current setup shows "2 steps", but mixes the provider and a short version of a consumer. It would make sense to actually show how prop-drilling is avoided instead.
So taking a look at the next
documentation it looks like this was mostly addressed. When is next
expected to be released? Since that change has been made I think it's fine to close this issue.
Closing this as Yew 0.21 has been released with the fix
This is about:
Problem AFAICT there isn't any documentation showing how you can use a context (create a context and consume it appropriately to update your component) that doesn't use function components.
e.g. In the
Contexts
documentation onyew.rs
it doesn't show how to update a Context and have it reflected.Details about the solution you'd like (Optional)
Just add to the existing documentation for
https://yew.rs/docs/concepts/contexts
- by including another section called updating context - it could simply show how you can update the context and have it reflected in your component.Additional context (Optional)
https://github.com/yewstack/yew/blob/master/examples/contexts/src/struct_component_subscriber.rs
<- shows a good example of how to do this, although it's unclear why you need to store aContextHandle<_>
Questionaire (Optional)