context_api.rs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //! Demonstrates cross-component state sharing using Dioxus' Context API
  2. //!
  3. //! Features:
  4. //! - Context provider initialization
  5. //! - Nested component consumption
  6. //! - Reactive state updates
  7. //! - Error handling for missing context
  8. //! - Platform-agnostic implementation
  9. use dioxus::prelude::*;
  10. const STYLE: Asset = asset!("/examples/assets/context_api.css");
  11. fn main() {
  12. launch(app);
  13. }
  14. #[component]
  15. fn app() -> Element {
  16. // Provide theme context at root level
  17. use_context_provider(|| Signal::new(Theme::Light));
  18. rsx! {
  19. document::Link { rel: "stylesheet", href: STYLE }
  20. main {
  21. class: "main-container",
  22. h1 { "Theme Switcher" }
  23. ThemeControls {}
  24. ThemeDisplay {}
  25. }
  26. }
  27. }
  28. #[derive(Clone, Copy, PartialEq, Debug)]
  29. enum Theme {
  30. Light,
  31. Dark,
  32. }
  33. impl Theme {
  34. fn stylesheet(&self) -> &'static str {
  35. match self {
  36. Theme::Light => "light-theme",
  37. Theme::Dark => "dark-theme",
  38. }
  39. }
  40. }
  41. #[component]
  42. fn ThemeControls() -> Element {
  43. let mut theme = use_theme_context();
  44. let current_theme = *theme.read();
  45. rsx! {
  46. div {
  47. class: "controls",
  48. button {
  49. class: "btn",
  50. onclick: move |_| theme.set(Theme::Light),
  51. disabled: current_theme== Theme::Light,
  52. "Switch to Light"
  53. }
  54. button {
  55. class: "btn",
  56. onclick: move |_| theme.set(Theme::Dark),
  57. disabled: current_theme == Theme::Dark,
  58. "Switch to Dark"
  59. }
  60. }
  61. }
  62. }
  63. #[component]
  64. fn ThemeDisplay() -> Element {
  65. let theme = use_theme_context();
  66. rsx! {
  67. div {
  68. class: "display {theme.read().stylesheet()}",
  69. p { "Current theme: {theme:?}" }
  70. p { "Try switching themes using the buttons above!" }
  71. }
  72. }
  73. }
  74. fn use_theme_context() -> Signal<Theme> {
  75. try_use_context::<Signal<Theme>>()
  76. .expect("Theme context not found. Ensure <App> is the root component.")
  77. }