use_context.rs 2.0 KB

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