leptos/provider.rs
1use crate::{children::TypedChildren, component, IntoView};
2use reactive_graph::owner::{provide_context, Owner};
3use tachys::reactive_graph::OwnedView;
4
5#[component]
6/// Uses the context API to [`provide_context`] to its children and descendants,
7/// without overwriting any contexts of the same type in its own reactive scope.
8///
9/// This prevents issues related to “context shadowing.”
10///
11/// ```rust
12/// use leptos::{context::Provider, prelude::*};
13///
14/// #[component]
15/// pub fn App() -> impl IntoView {
16/// // each Provider will only provide the value to its children
17/// view! {
18/// <Provider value=1u8>
19/// // correctly gets 1 from context
20/// {use_context::<u8>().unwrap_or(0)}
21/// </Provider>
22/// <Provider value=2u8>
23/// // correctly gets 2 from context
24/// {use_context::<u8>().unwrap_or(0)}
25/// </Provider>
26/// // does not find any u8 in context
27/// {use_context::<u8>().unwrap_or(0)}
28/// }
29/// }
30/// ```
31pub fn Provider<T, Chil>(
32 /// The value to be provided via context.
33 value: T,
34 children: TypedChildren<Chil>,
35) -> impl IntoView
36where
37 T: Send + Sync + 'static,
38 Chil: IntoView + 'static,
39{
40 let owner = Owner::current()
41 .expect("no current reactive Owner found")
42 .child();
43 let children = children.into_inner();
44 let children = owner.with(|| {
45 provide_context(value);
46 children()
47 });
48 OwnedView::new_with_owner(children, owner)
49}