From e055182f9352cead946325a4ec8c226fd6a0198a Mon Sep 17 00:00:00 2001 From: Richard LASJUNIES Date: Fri, 8 May 2020 18:41:56 +0200 Subject: [PATCH 1/2] add trap events page --- src/concepts/components/trapevents.md | 311 ++++++++++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 src/concepts/components/trapevents.md diff --git a/src/concepts/components/trapevents.md b/src/concepts/components/trapevents.md new file mode 100644 index 0000000..a493e5e --- /dev/null +++ b/src/concepts/components/trapevents.md @@ -0,0 +1,311 @@ +--- +description: Component could mutate internal state or re-render based on events emitted by html or yew components +--- + +# Trap events and mutate state + +The framework provide the capability to update the internal state, for example, when an event is emitted by a child component. + +The `update` method could be called and mutate the internal state. The `update` method is called via `self.link.callback`, `link` being an attribute of the component struct. + +The `update` method receives "context" by the argument `msg` of type `Self::Message`. You can define any type for `Message`. The common way is to define an enum `Msg` for any action that can mutate the state. Then define `Msg` as the type of `Message` in the Component trait implementation. + +At the end of the `update` method, you can decide to render the component returning `true`. + +```rust +use yew::prelude::*; + +pub struct TrapEventComponent { + link: ComponentLink, + + name: String, + show_message: bool, +} + +pub enum Msg { + Click(), +} + +impl Component for TrapEventComponent { + type Message = Msg; + type Properties = (); + + fn create(_props: Self::Properties, link: ComponentLink) -> Self { + Self { + link, + name: "Clark".into(), + show_message: false, + } + } + + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::Click() => self.show_message = true, + } + true + } + + fn change(&mut self, _props: Self::Properties) -> ShouldRender { + true + } + + fn view(&self) -> Html { + if !self.show_message { + html! { + <> + + + } + } else { + html! { + <> +

{format!("Hello {}",self.name)}

+ + } + } + } +} +``` + +## Define the `link` attribute in the state + +```rust +# use yew::prelude::*; +// ... + pub struct TrapEventComponent { + link: ComponentLink, + +// ... +# name: String, +# show_message: bool, +# } +# +# pub enum Msg { +# Click(), +# } +# +# impl Component for TrapEventComponent { +# type Message = Msg; +# type Properties = (); +# +# fn create(_props: Self::Properties, link: ComponentLink) -> Self { +# Self { +# link, +# name: "Clark".into(), +# show_message: false, +# } +# } +# +# fn update(&mut self, msg: Self::Message) -> ShouldRender { +# match msg { +# Msg::Click() => self.show_message = true, +# } +# true +# } +# +# fn change(&mut self, _props: Self::Properties) -> ShouldRender { +# true +# } +# +# fn view(&self) -> Html { +# if !self.show_message { +# html! { +# <> +# +# +# } +# } else { +# html! { +# <> +#

{format!("Hello {}",self.name)}

+# +# } +# } +# } +# } +``` + +## Define a Message enum + +```rust +# use yew::prelude::*; +# +# pub struct TrapEventComponent { +# link: ComponentLink, +# +# name: String, +# show_message: bool, +# } + +// ... +pub enum Msg { + Click(), +} + +impl Component for TrapEventComponent { + type Message = Msg; + type Properties = (); + +// ... +# fn create(_props: Self::Properties, link: ComponentLink) -> Self { +# Self { +# link, +# name: "Clark".into(), +# show_message: false, +# } +# } +# +# fn update(&mut self, msg: Self::Message) -> ShouldRender { +# match msg { +# Msg::Click() => self.show_message = true, +# } +# true +# } +# +# fn change(&mut self, _props: Self::Properties) -> ShouldRender { +# true +# } +# +# fn view(&self) -> Html { +# if !self.show_message { +# html! { +# <> +# +# +# } +# } else { +# html! { +# <> +#

{format!("Hello {}",self.name)}

+# +# } +# } +# } +# } + + + + + +``` + +## Update the internal state based on the context + +```rust +# use yew::prelude::*; +# +# pub struct TrapEventComponent { +# link: ComponentLink, +# +# name: String, +# show_message: bool, +# } +# +# pub enum Msg { +# Click(), +# } +# +# impl Component for TrapEventComponent { +# type Message = Msg; +# type Properties = (); +# +# fn create(_props: Self::Properties, link: ComponentLink) -> Self { +# Self { +# link, +# name: "Clark".into(), +# show_message: false, +# } +# } + +// ... + fn update(&mut self, msg: Self::Message) -> ShouldRender { + match msg { + Msg::Click() => self.show_message = true, + } + true + } +// ... + +# fn change(&mut self, _props: Self::Properties) -> ShouldRender { +# true +# } +# +# fn view(&self) -> Html { +# if !self.show_message { +# html! { +# <> +# +# +# } +# } else { +# html! { +# <> +#

{format!("Hello {}",self.name)}

+# +# } +# } +# } +# } + +``` + +## Trap the html native events + +```rust +# use yew::prelude::*; +# +# pub struct TrapEventComponent { +# link: ComponentLink, +# +# name: String, +# show_message: bool, +# } +# +# pub enum Msg { +# Click(), +# } +# +# impl Component for TrapEventComponent { +# type Message = Msg; +# type Properties = (); +# +# fn create(_props: Self::Properties, link: ComponentLink) -> Self { +# Self { +# link, +# name: "Clark".into(), +# show_message: false, +# } +# } +# +# fn update(&mut self, msg: Self::Message) -> ShouldRender { +# match msg { +# Msg::Click() => self.show_message = true, +# } +# true +# } +# +# fn change(&mut self, _props: Self::Properties) -> ShouldRender { +# true +# } +# +# fn view(&self) -> Html { +# if !self.show_message { +// ... + html! { + <> + + +// ... +# } +# } else { +# html! { +# <> +#

{format!("Hello {}",self.name)}

+# +# } +# } +# } +# } +``` + +**TODO: extend adding the treatment based on an event state or redirect to example** From 646741cd063d6586bfc2b546e058db6a7079e925 Mon Sep 17 00:00:00 2001 From: Richard LASJUNIES Date: Sun, 10 May 2020 10:39:22 +0200 Subject: [PATCH 2/2] Update following Teymour feed-backs --- src/concepts/components/trapevents.md | 231 ++------------------------ 1 file changed, 18 insertions(+), 213 deletions(-) diff --git a/src/concepts/components/trapevents.md b/src/concepts/components/trapevents.md index a493e5e..cba8750 100644 --- a/src/concepts/components/trapevents.md +++ b/src/concepts/components/trapevents.md @@ -1,8 +1,8 @@ --- -description: Component could mutate internal state or re-render based on events emitted by html or yew components +description: Component could mutate internal state or re-render based on events emitted by html or Yew components --- -# Trap events and mutate state +# Listen to events and mutate state The framework provide the capability to update the internal state, for example, when an event is emitted by a child component. @@ -10,23 +10,22 @@ The `update` method could be called and mutate the internal state. The `update` The `update` method receives "context" by the argument `msg` of type `Self::Message`. You can define any type for `Message`. The common way is to define an enum `Msg` for any action that can mutate the state. Then define `Msg` as the type of `Message` in the Component trait implementation. -At the end of the `update` method, you can decide to render the component returning `true`. +You can decide to render the component returning `true` from the `Update` method. ```rust use yew::prelude::*; -pub struct TrapEventComponent { +pub struct ListenEventComponent { link: ComponentLink, - name: String, show_message: bool, } pub enum Msg { - Click(), + Click, } -impl Component for TrapEventComponent { +impl Component for ListenEventComponent { type Message = Msg; type Properties = (); @@ -40,7 +39,7 @@ impl Component for TrapEventComponent { fn update(&mut self, msg: Self::Message) -> ShouldRender { match msg { - Msg::Click() => self.show_message = true, + Msg::Click => self.show_message = true, } true } @@ -53,259 +52,65 @@ impl Component for TrapEventComponent { if !self.show_message { html! { <> - + } } else { html! { <> -

{format!("Hello {}",self.name)}

+

{format!("Hello {}", self.name)}

} } } } + ``` ## Define the `link` attribute in the state ```rust -# use yew::prelude::*; // ... - pub struct TrapEventComponent { - link: ComponentLink, - +pub struct ListenEventComponent { + link: ComponentLink, // ... -# name: String, -# show_message: bool, -# } -# -# pub enum Msg { -# Click(), -# } -# -# impl Component for TrapEventComponent { -# type Message = Msg; -# type Properties = (); -# -# fn create(_props: Self::Properties, link: ComponentLink) -> Self { -# Self { -# link, -# name: "Clark".into(), -# show_message: false, -# } -# } -# -# fn update(&mut self, msg: Self::Message) -> ShouldRender { -# match msg { -# Msg::Click() => self.show_message = true, -# } -# true -# } -# -# fn change(&mut self, _props: Self::Properties) -> ShouldRender { -# true -# } -# -# fn view(&self) -> Html { -# if !self.show_message { -# html! { -# <> -# -# -# } -# } else { -# html! { -# <> -#

{format!("Hello {}",self.name)}

-# -# } -# } -# } -# } ``` ## Define a Message enum ```rust -# use yew::prelude::*; -# -# pub struct TrapEventComponent { -# link: ComponentLink, -# -# name: String, -# show_message: bool, -# } // ... pub enum Msg { - Click(), + Click, } -impl Component for TrapEventComponent { +impl Component for ListenEventComponent { type Message = Msg; type Properties = (); // ... -# fn create(_props: Self::Properties, link: ComponentLink) -> Self { -# Self { -# link, -# name: "Clark".into(), -# show_message: false, -# } -# } -# -# fn update(&mut self, msg: Self::Message) -> ShouldRender { -# match msg { -# Msg::Click() => self.show_message = true, -# } -# true -# } -# -# fn change(&mut self, _props: Self::Properties) -> ShouldRender { -# true -# } -# -# fn view(&self) -> Html { -# if !self.show_message { -# html! { -# <> -# -# -# } -# } else { -# html! { -# <> -#

{format!("Hello {}",self.name)}

-# -# } -# } -# } -# } - - - - - ``` ## Update the internal state based on the context ```rust -# use yew::prelude::*; -# -# pub struct TrapEventComponent { -# link: ComponentLink, -# -# name: String, -# show_message: bool, -# } -# -# pub enum Msg { -# Click(), -# } -# -# impl Component for TrapEventComponent { -# type Message = Msg; -# type Properties = (); -# -# fn create(_props: Self::Properties, link: ComponentLink) -> Self { -# Self { -# link, -# name: "Clark".into(), -# show_message: false, -# } -# } - // ... fn update(&mut self, msg: Self::Message) -> ShouldRender { match msg { - Msg::Click() => self.show_message = true, + Msg::Click => self.show_message = true, } true } // ... - -# fn change(&mut self, _props: Self::Properties) -> ShouldRender { -# true -# } -# -# fn view(&self) -> Html { -# if !self.show_message { -# html! { -# <> -# -# -# } -# } else { -# html! { -# <> -#

{format!("Hello {}",self.name)}

-# -# } -# } -# } -# } - ``` -## Trap the html native events +## Register to the html events ```rust -# use yew::prelude::*; -# -# pub struct TrapEventComponent { -# link: ComponentLink, -# -# name: String, -# show_message: bool, -# } -# -# pub enum Msg { -# Click(), -# } -# -# impl Component for TrapEventComponent { -# type Message = Msg; -# type Properties = (); -# -# fn create(_props: Self::Properties, link: ComponentLink) -> Self { -# Self { -# link, -# name: "Clark".into(), -# show_message: false, -# } -# } -# -# fn update(&mut self, msg: Self::Message) -> ShouldRender { -# match msg { -# Msg::Click() => self.show_message = true, -# } -# true -# } -# -# fn change(&mut self, _props: Self::Properties) -> ShouldRender { -# true -# } -# -# fn view(&self) -> Html { -# if !self.show_message { + // ... html! { - <> - - + // ... -# } -# } else { -# html! { -# <> -#

{format!("Hello {}",self.name)}

-# -# } -# } -# } -# } ``` - -**TODO: extend adding the treatment based on an event state or redirect to example**