use_context.rs 2.4 KB

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