diff --git a/Cargo.lock b/Cargo.lock index 3cfae99c9..f22270ec2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -493,7 +493,6 @@ dependencies = [ name = "contexts" version = "0.1.0" dependencies = [ - "serde", "yew", "yew-agent", ] diff --git a/examples/contexts/Cargo.toml b/examples/contexts/Cargo.toml index 65097ec6e..cd63a9b11 100644 --- a/examples/contexts/Cargo.toml +++ b/examples/contexts/Cargo.toml @@ -5,6 +5,5 @@ edition = "2021" license = "MIT OR Apache-2.0" [dependencies] -serde = { version = "1.0", features = ["derive"] } yew = { path = "../../packages/yew", features = ["csr"] } yew-agent = { path = "../../packages/yew-agent" } diff --git a/examples/contexts/src/main.rs b/examples/contexts/src/main.rs index d6531e49b..4512ee3aa 100644 --- a/examples/contexts/src/main.rs +++ b/examples/contexts/src/main.rs @@ -1,10 +1,12 @@ mod msg_ctx; mod producer; +mod struct_component_producer; mod struct_component_subscriber; mod subscriber; use msg_ctx::MessageProvider; use producer::Producer; +use struct_component_producer::StructComponentProducer; use struct_component_subscriber::StructComponentSubscriber; use subscriber::Subscriber; use yew::prelude::*; @@ -14,6 +16,7 @@ pub fn App() -> Html { html! { + diff --git a/examples/contexts/src/producer.rs b/examples/contexts/src/producer.rs index 9eddc57a4..1a1aaadca 100644 --- a/examples/contexts/src/producer.rs +++ b/examples/contexts/src/producer.rs @@ -6,10 +6,8 @@ use super::msg_ctx::MessageContext; pub fn Producer() -> Html { let msg_ctx = use_context::().unwrap(); - let onclick = Callback::from(move |_| msg_ctx.dispatch("Message Received.".to_string())); - html! { - } diff --git a/examples/contexts/src/struct_component_producer.rs b/examples/contexts/src/struct_component_producer.rs new file mode 100644 index 000000000..49e1f02d6 --- /dev/null +++ b/examples/contexts/src/struct_component_producer.rs @@ -0,0 +1,27 @@ +use yew::prelude::*; + +use super::msg_ctx::MessageContext; + +pub struct StructComponentProducer; + +impl Component for StructComponentProducer { + type Message = (); + type Properties = (); + + fn create(_ctx: &Context) -> Self { + Self + } + + fn view(&self, ctx: &Context) -> Html { + let (msg_ctx, _) = ctx + .link() + .context::(Callback::noop()) + .expect("No Message Context Provided"); + + html! { + + } + } +} diff --git a/packages/yew/src/functional/hooks/use_context.rs b/packages/yew/src/functional/hooks/use_context.rs index c85cadfa5..9310192fb 100644 --- a/packages/yew/src/functional/hooks/use_context.rs +++ b/packages/yew/src/functional/hooks/use_context.rs @@ -11,7 +11,7 @@ use crate::functional::{Hook, HookContext}; /// is returned. A component which calls `use_context` will re-render when the data of the context /// changes. /// -/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs). +/// More information about contexts and how to define and consume them can be found on [Yew Docs](https://yew.rs/docs/concepts/contexts). /// /// # Example /// diff --git a/website/docs/concepts/contexts.mdx b/website/docs/concepts/contexts.mdx index 230f8daa6..bbe65f7f3 100644 --- a/website/docs/concepts/contexts.mdx +++ b/website/docs/concepts/contexts.mdx @@ -96,35 +96,57 @@ A context provider is required to consume the context. `ContextProvider`, whe The children are re-rendered when the context changes. A struct is used to define what data is to be passed. The `ContextProvider` can be used as: ```rust -use std::rc::Rc; use yew::prelude::*; + +/// App theme #[derive(Clone, Debug, PartialEq)] struct Theme { foreground: String, background: String, } +/// Main component #[function_component] -fn NavButton() -> Html { - let theme = use_context::(); - - html! { - // use theme - } -} - -#[function_component] -fn App() -> Html { - let theme = use_memo((), |_| Theme { - foreground: "yellow".to_owned(), - background: "pink".to_owned(), +pub fn App() -> Html { + let ctx = use_state(|| Theme { + foreground: "#000000".to_owned(), + background: "#eeeeee".to_owned(), }); html! { - > context={theme}> - - >> + // `ctx` is type `Rc>` while we need `Theme` + // so we deref it. + // It derefs to `&Theme`, hence the clone + context={(*ctx).clone()}> + // Every child here and their children will have access to this context. + + > + } +} + +/// The toolbar. +/// This component has access to the context +#[function_component] +pub fn Toolbar() -> Html { + html! { +
+ +
+ } +} + +/// Button placed in `Toolbar`. +/// As this component is a child of `ThemeContextProvider` in the component tree, it also has access +/// to the context. +#[function_component] +pub fn ThemedButton() -> Html { + let theme = use_context::().expect("no ctx found"); + + html! { + } } ```