dioxus_hooks/
use_context.rs

1use dioxus_core::{
2    prelude::{consume_context, provide_context, try_consume_context},
3    use_hook,
4};
5
6/// Consume some context in the tree, providing a sharable handle to the value
7///
8/// Does not regenerate the value if the value is changed at the parent.
9#[doc = include_str!("../docs/rules_of_hooks.md")]
10#[doc = include_str!("../docs/moving_state_around.md")]
11#[must_use]
12pub fn try_use_context<T: 'static + Clone>() -> Option<T> {
13    use_hook(|| try_consume_context::<T>())
14}
15
16/// Consume some context in the tree, providing a sharable handle to the value
17///
18/// Does not regenerate the value if the value is changed at the parent.
19/// ```rust
20/// # use dioxus::prelude::*;
21/// # #[derive(Clone, Copy, PartialEq, Debug)]
22/// # enum Theme { Dark, Light }
23/// fn Parent() -> Element {
24///     use_context_provider(|| Theme::Dark);
25///     rsx! { Child {} }
26/// }
27/// #[component]
28/// fn Child() -> Element {
29///     //gets context provided by parent element with use_context_provider
30///     let user_theme = use_context::<Theme>();
31///     rsx! { "user using dark mode: {user_theme == Theme::Dark}" }
32/// }
33/// ```
34#[doc = include_str!("../docs/rules_of_hooks.md")]
35#[doc = include_str!("../docs/moving_state_around.md")]
36#[must_use]
37pub fn use_context<T: 'static + Clone>() -> T {
38    use_hook(|| consume_context::<T>())
39}
40
41/// Provide some context via the tree and return a reference to it
42///
43/// Once the context has been provided, it is immutable. Mutations should be done via interior mutability.
44/// Context can be read by any child components of the context provider, and is a solution to prop
45/// drilling, using a context provider with a Signal inside is a good way to provide global/shared
46/// state in your app:
47/// ```rust
48/// # use dioxus::prelude::*;
49///fn app() -> Element {
50///    use_context_provider(|| Signal::new(0));
51///    rsx! { Child {} }
52///}
53/// // This component does read from the signal, so when the signal changes it will rerun
54///#[component]
55///fn Child() -> Element {
56///     let mut signal: Signal<i32> = use_context();
57///     rsx! {
58///         button { onclick: move |_| signal += 1, "increment context" }
59///         p {"{signal}"}
60///     }
61///}
62/// ```
63#[doc = include_str!("../docs/rules_of_hooks.md")]
64#[doc = include_str!("../docs/moving_state_around.md")]
65pub fn use_context_provider<T: 'static + Clone>(f: impl FnOnce() -> T) -> T {
66    use_hook(|| provide_context(f()))
67}