From a956068fb901a677c723eb4d242d20b7fe12f160 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 17:48:01 +0500 Subject: [PATCH 1/9] yeet Callback::once --- packages/yew-agent/src/link.rs | 22 ------ packages/yew/src/callback.rs | 98 +++++++++--------------- packages/yew/src/html/component/scope.rs | 75 +----------------- packages/yew/src/html/listener/events.rs | 6 +- 4 files changed, 39 insertions(+), 162 deletions(-) diff --git a/packages/yew-agent/src/link.rs b/packages/yew-agent/src/link.rs index d2076f0d5bb..9d7ef52f10c 100644 --- a/packages/yew-agent/src/link.rs +++ b/packages/yew-agent/src/link.rs @@ -91,28 +91,6 @@ impl AgentLink { closure.into() } - /// This method creates a [`Callback`] from [`FnOnce`] which returns a Future - /// which returns a message to be sent back to the agent. - /// - /// # Panics - /// If the future panics, then the promise will not resolve, and - /// will leak. - pub fn callback_future_once(&self, function: FN) -> Callback - where - M: Into, - FU: Future + 'static, - FN: FnOnce(IN) -> FU + 'static, - { - let link = self.clone(); - - let closure = move |input: IN| { - let future: FU = function(input); - link.send_future(future); - }; - - Callback::once(closure) - } - /// This method processes a Future that returns a message and sends it back to the agent. /// /// # Panics diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index 58fba1953a3..7113894620a 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -5,7 +5,6 @@ //! - [Timer](https://github.com/yewstack/yew/tree/master/examples/timer) use crate::html::ImplicitClone; -use std::cell::RefCell; use std::fmt; use std::rc::Rc; @@ -16,114 +15,89 @@ use std::rc::Rc; /// Callbacks should be used from JS callbacks or `setTimeout` calls. /// /// An `Rc` wrapper is used to make it cloneable. -pub enum Callback { - /// A callback which can be called multiple times with optional modifier flags - Callback { - /// A callback which can be called multiple times - cb: Rc, - - /// Setting `passive` to [Some] explicitly makes the event listener passive or not. - /// Yew sets sane defaults depending on the type of the listener. - /// See - /// [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). - passive: Option, - }, - - /// A callback which can only be called once. The callback will panic if it is - /// called more than once. - CallbackOnce(Rc>), +pub struct Callback { + /// A callback which can be called multiple times + pub(crate) cb: Rc OUT>, + + /// Setting `passive` to [Some] explicitly makes the event listener passive or not. + /// Yew sets sane defaults depending on the type of the listener. + /// See + /// [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). + pub(crate) passive: Option, } -type CallbackOnce = RefCell>>; - -impl From for Callback { +impl OUT + 'static> From for Callback { fn from(func: F) -> Self { - Callback::Callback { + Callback { cb: Rc::new(func), passive: None, } } } -impl Clone for Callback { +impl Clone for Callback { fn clone(&self) -> Self { - match self { - Callback::Callback { cb, passive } => Callback::Callback { - cb: cb.clone(), - passive: *passive, - }, - Callback::CallbackOnce(cb) => Callback::CallbackOnce(cb.clone()), + Self { + cb: self.cb.clone(), + passive: self.passive, } } } #[allow(clippy::vtable_address_comparisons)] -impl PartialEq for Callback { - fn eq(&self, other: &Callback) -> bool { +impl PartialEq for Callback { + fn eq(&self, other: &Callback) -> bool { match (&self, &other) { - (Callback::CallbackOnce(cb), Callback::CallbackOnce(other_cb)) => { - Rc::ptr_eq(cb, other_cb) - } ( - Callback::Callback { cb, passive }, - Callback::Callback { + Callback { cb, passive }, + Callback { cb: rhs_cb, passive: rhs_passive, }, ) => Rc::ptr_eq(cb, rhs_cb) && passive == rhs_passive, - _ => false, } } } -impl fmt::Debug for Callback { +impl fmt::Debug for Callback { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let data = match self { - Callback::Callback { .. } => "Callback<_>", - Callback::CallbackOnce(_) => "CallbackOnce<_>", + Callback { .. } => "Callback<_>", }; f.write_str(data) } } -impl Callback { - /// This method calls the callback's function. - pub fn emit(&self, value: IN) { - match self { - Callback::Callback { cb, .. } => cb(value), - Callback::CallbackOnce(rc) => { - let cb = rc.replace(None); - let f = cb.expect("callback contains `FnOnce` which has already been used"); - f(value) - } - }; +impl Callback { + /// Creates a new callback. + pub fn new(cb: impl Fn(IN) -> OUT + 'static, passive: Option) -> Self { + Self { + cb: Rc::new(cb), + passive, + } } - /// Creates a callback from an `FnOnce`. The programmer is responsible for ensuring - /// that the callback is only called once. If it is called more than once, the callback - /// will panic. - pub fn once(func: F) -> Self - where - F: FnOnce(IN) + 'static, - { - Callback::CallbackOnce(Rc::new(RefCell::new(Some(Box::new(func))))) + /// This method calls the callback's function. + pub fn emit(&self, value: IN) -> OUT { + (*self.cb)(value) } +} +impl Callback { /// Creates a "no-op" callback which can be used when it is not suitable to use an /// `Option`. pub fn noop() -> Self { - Self::from(|_| {}) + Self::new(|_| (), None) } } - impl Default for Callback { fn default() -> Self { Self::noop() } } -impl Callback { +impl Callback { /// Changes the input type of the callback to another. /// Works like the `map` method but in the opposite direction. pub fn reform(&self, func: F) -> Callback @@ -139,4 +113,4 @@ impl Callback { } } -impl ImplicitClone for Callback {} +impl ImplicitClone for Callback {} diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index ef88d11ad1d..2710ddc265e 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -333,29 +333,7 @@ impl Scope { let output = function(input); scope.send_message(output); }; - Callback::Callback { - passive: passive.into(), - cb: Rc::new(closure), - } - } - - /// Creates a `Callback` from an `FnOnce` which will send a message - /// to the linked component's update method when invoked. - /// - /// Please be aware that currently the result of this callback - /// will synchronously schedule calls to the - /// [Component](Component) interface. - pub fn callback_once(&self, function: F) -> Callback - where - M: Into, - F: FnOnce(IN) -> M + 'static, - { - let scope = self.clone(); - let closure = move |input| { - let output = function(input); - scope.send_message(output); - }; - Callback::once(closure) + Callback::new(closure, passive.into()) } /// Creates a `Callback` which will send a batch of messages back @@ -386,34 +364,6 @@ impl Scope { closure.into() } - /// Creates a `Callback` from an `FnOnce` which will send a batch of messages back - /// to the linked component's update method when invoked. - /// - /// The callback function's return type is generic to allow for dealing with both - /// `Option` and `Vec` nicely. `Option` can be used when dealing with a callback that - /// might not need to send an update. - /// - /// ```ignore - /// link.batch_callback_once(|_| vec![Msg::A, Msg::B]); - /// link.batch_callback_once(|_| Some(Msg::A)); - /// ``` - /// - /// Please be aware that currently the results of these callbacks - /// will synchronously schedule calls to the - /// [Component](Component) interface. - pub fn batch_callback_once(&self, function: F) -> Callback - where - F: FnOnce(IN) -> OUT + 'static, - OUT: SendAsMessage, - { - let scope = self.clone(); - let closure = move |input| { - let messages = function(input); - messages.send(&scope); - }; - Callback::once(closure) - } - /// This method creates a [`Callback`] which returns a Future which /// returns a message to be sent back to the component's event /// loop. @@ -437,29 +387,6 @@ impl Scope { closure.into() } - /// This method creates a [`Callback`] from [`FnOnce`] which returns a Future - /// which returns a message to be sent back to the component's event - /// loop. - /// - /// # Panics - /// If the future panics, then the promise will not resolve, and - /// will leak. - pub fn callback_future_once(&self, function: FN) -> Callback - where - M: Into, - FU: Future + 'static, - FN: FnOnce(IN) -> FU + 'static, - { - let link = self.clone(); - - let closure = move |input: IN| { - let future: FU = function(input); - link.send_future(future); - }; - - Callback::once(closure) - } - /// This method processes a Future that returns a message and sends it back to the component's /// loop. /// diff --git a/packages/yew/src/html/listener/events.rs b/packages/yew/src/html/listener/events.rs index db11fd8d1c9..b289b64c4b9 100644 --- a/packages/yew/src/html/listener/events.rs +++ b/packages/yew/src/html/listener/events.rs @@ -47,10 +47,8 @@ macro_rules! impl_action { } fn passive(&self) -> bool { - match &self.callback { - Callback::Callback{passive, ..} => (*passive).unwrap_or($passive), - _ => $passive, - } + let Callback { passive, .. } = &self.callback; + (*passive).unwrap_or($passive) } } } From 33e7770d825580e9b9b8641958f402a9c2fb70fa Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 18:07:01 +0500 Subject: [PATCH 2/9] yeet Callback::reform --- examples/boids/src/slider.rs | 12 ++++--- .../function_todomvc/src/components/entry.rs | 27 ++++++++++---- .../function_todomvc/src/components/filter.rs | 7 +++- .../src/hooks/use_bool_toggle.rs | 36 +++++++------------ examples/nested_list/src/header.rs | 11 +++--- examples/nested_list/src/item.rs | 7 ++-- examples/nested_list/src/list.rs | 11 +++--- packages/yew/src/callback.rs | 16 --------- 8 files changed, 65 insertions(+), 62 deletions(-) diff --git a/examples/boids/src/slider.rs b/examples/boids/src/slider.rs index c5126352353..87f608b7f76 100644 --- a/examples/boids/src/slider.rs +++ b/examples/boids/src/slider.rs @@ -68,10 +68,14 @@ impl Component for Slider { 10f64.powi(-(p as i32)) }); - let oninput = onchange.reform(|e: InputEvent| { - let input: HtmlInputElement = e.target_unchecked_into(); - input.value_as_number() - }); + let oninput = { + let onchange = onchange.clone(); + Callback::from(move |e: InputEvent| { + let input: HtmlInputElement = e.target_unchecked_into(); + let output = input.value_as_number(); + onchange.emit(output); + }) + }; html! {
diff --git a/examples/function_todomvc/src/components/entry.rs b/examples/function_todomvc/src/components/entry.rs index 79104a6af4d..18b3f507a17 100644 --- a/examples/function_todomvc/src/components/entry.rs +++ b/examples/function_todomvc/src/components/entry.rs @@ -1,4 +1,4 @@ -use crate::hooks::use_bool_toggle::use_bool_toggle; +use crate::hooks::use_bool_toggle::{use_bool_toggle, UseBoolToggleHandle}; use crate::state::Entry as Item; use web_sys::{HtmlInputElement, MouseEvent}; use yew::events::{Event, FocusEvent, KeyboardEvent}; @@ -37,6 +37,23 @@ pub fn entry(props: &EntryProps) -> Html { class.push("completed"); } + let ontoggle = { + let ontoggle = props.ontoggle.clone(); + move |_| ontoggle.emit(id) + }; + + let onremove = { + let onremove = props.onremove.clone(); + move |_| onremove.emit(id) + }; + + let ondblclick = { + let edit_toggle = UseBoolToggleHandle::clone(&edit_toggle); + move |_| { + edit_toggle.clone().toggle(); + } + }; + html! {
  • @@ -44,14 +61,12 @@ pub fn entry(props: &EntryProps) -> Html { type="checkbox" class="toggle" checked={props.entry.completed} - onclick={props.ontoggle.reform(move |_| id)} + onclick={ontoggle} /> -
  • diff --git a/examples/function_todomvc/src/components/filter.rs b/examples/function_todomvc/src/components/filter.rs index 4380d063cdf..f295aed06de 100644 --- a/examples/function_todomvc/src/components/filter.rs +++ b/examples/function_todomvc/src/components/filter.rs @@ -18,11 +18,16 @@ pub fn Filter(props: &FilterProps) -> Html { "not-selected" }; + let onset_filter = { + let onset_filter = props.onset_filter.clone(); + move |_| onset_filter.emit(filter) + }; + html! {
  • { props.filter } diff --git a/examples/function_todomvc/src/hooks/use_bool_toggle.rs b/examples/function_todomvc/src/hooks/use_bool_toggle.rs index 1ca6ae55b70..42662600c70 100644 --- a/examples/function_todomvc/src/hooks/use_bool_toggle.rs +++ b/examples/function_todomvc/src/hooks/use_bool_toggle.rs @@ -1,9 +1,10 @@ use std::ops::Deref; use std::rc::Rc; -use yew::functional::use_hook; +use yew::{use_state_eq, UseStateHandle}; +#[derive(Clone)] pub struct UseBoolToggleHandle { - value: bool, + value: UseStateHandle, toggle: Rc, } @@ -43,28 +44,15 @@ impl Deref for UseBoolToggleHandle { /// ... /// ``` pub fn use_bool_toggle(default: bool) -> UseBoolToggleHandle { - use_hook( - || default, - move |hook, updater| { - updater.post_render(move |state: &mut bool| { - if *state != default { - *state = default; - } - false - }); + let state = use_state_eq(|| default); - let toggle = Rc::new(move || { - updater.callback(move |st: &mut bool| { - *st = !*st; - true - }) - }); + let toggle = { + let state = state.clone(); + Rc::new(move || state.set(!*state)) + }; - UseBoolToggleHandle { - value: *hook, - toggle, - } - }, - |_| {}, - ) + UseBoolToggleHandle { + value: state.clone(), + toggle, + } } diff --git a/examples/nested_list/src/header.rs b/examples/nested_list/src/header.rs index dbad68b6034..bb8daa0e670 100644 --- a/examples/nested_list/src/header.rs +++ b/examples/nested_list/src/header.rs @@ -21,10 +21,13 @@ impl Component for ListHeader { fn view(&self, ctx: &Context) -> Html { let list_link = ctx.props().list_link.borrow().clone().unwrap(); - let onmouseover = ctx.props().on_hover.reform(|e: MouseEvent| { - e.stop_propagation(); - Hovered::Header - }); + let onmouseover = { + let on_hover = ctx.props().on_hover.clone(); + move |e: MouseEvent| { + e.stop_propagation(); + on_hover.emit(Hovered::Header) + } + }; html! {
    ) -> Html { let onmouseover = { let name = ctx.props().name.clone(); - ctx.props().on_hover.reform(move |e: MouseEvent| { + let on_hover = ctx.props().on_hover.clone(); + move |e: MouseEvent| { e.stop_propagation(); - Hovered::Item(name.clone()) - }) + on_hover.emit(Hovered::Item(name.clone())) + } }; html! {
    diff --git a/examples/nested_list/src/list.rs b/examples/nested_list/src/list.rs index 91e6db2acb2..36729824438 100644 --- a/examples/nested_list/src/list.rs +++ b/examples/nested_list/src/list.rs @@ -90,10 +90,13 @@ impl Component for List { fn view(&self, ctx: &Context) -> Html { let inactive = if self.inactive { "inactive" } else { "" }; - let onmouseover = ctx.props().on_hover.reform(|e: MouseEvent| { - e.stop_propagation(); - Hovered::List - }); + let onmouseover = { + let on_hover = ctx.props().on_hover.clone(); + move |e: MouseEvent| { + e.stop_propagation(); + on_hover.emit(Hovered::List); + } + }; html! {
    diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index 7113894620a..ec317c391bb 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -97,20 +97,4 @@ impl Default for Callback { } } -impl Callback { - /// Changes the input type of the callback to another. - /// Works like the `map` method but in the opposite direction. - pub fn reform(&self, func: F) -> Callback - where - F: Fn(T) -> IN + 'static, - { - let this = self.clone(); - let func = move |input| { - let output = func(input); - this.emit(output); - }; - Callback::from(func) - } -} - impl ImplicitClone for Callback {} From 7c204c9455be1c48008f074971000566979875c5 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 18:15:32 +0500 Subject: [PATCH 3/9] remove passive overrides Event's passive state will be determined by sane defaults set by Yew --- packages/yew/src/callback.rs | 33 +++-------------------- packages/yew/src/html/component/scope.rs | 25 +---------------- packages/yew/src/html/listener/events.rs | 3 +-- packages/yew/src/virtual_dom/listeners.rs | 20 +------------- 4 files changed, 7 insertions(+), 74 deletions(-) diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index ec317c391bb..75191433561 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -18,20 +18,11 @@ use std::rc::Rc; pub struct Callback { /// A callback which can be called multiple times pub(crate) cb: Rc OUT>, - - /// Setting `passive` to [Some] explicitly makes the event listener passive or not. - /// Yew sets sane defaults depending on the type of the listener. - /// See - /// [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). - pub(crate) passive: Option, } impl OUT + 'static> From for Callback { fn from(func: F) -> Self { - Callback { - cb: Rc::new(func), - passive: None, - } + Callback { cb: Rc::new(func) } } } @@ -39,7 +30,6 @@ impl Clone for Callback { fn clone(&self) -> Self { Self { cb: self.cb.clone(), - passive: self.passive, } } } @@ -47,15 +37,8 @@ impl Clone for Callback { #[allow(clippy::vtable_address_comparisons)] impl PartialEq for Callback { fn eq(&self, other: &Callback) -> bool { - match (&self, &other) { - ( - Callback { cb, passive }, - Callback { - cb: rhs_cb, - passive: rhs_passive, - }, - ) => Rc::ptr_eq(cb, rhs_cb) && passive == rhs_passive, - } + let (Callback { cb }, Callback { cb: rhs_cb }) = (self, other); + Rc::ptr_eq(cb, rhs_cb) } } @@ -70,14 +53,6 @@ impl fmt::Debug for Callback { } impl Callback { - /// Creates a new callback. - pub fn new(cb: impl Fn(IN) -> OUT + 'static, passive: Option) -> Self { - Self { - cb: Rc::new(cb), - passive, - } - } - /// This method calls the callback's function. pub fn emit(&self, value: IN) -> OUT { (*self.cb)(value) @@ -88,7 +63,7 @@ impl Callback { /// Creates a "no-op" callback which can be used when it is not suitable to use an /// `Option`. pub fn noop() -> Self { - Self::new(|_| (), None) + Self::from(|_| ()) } } impl Default for Callback { diff --git a/packages/yew/src/html/component/scope.rs b/packages/yew/src/html/component/scope.rs index 2710ddc265e..484f3918eb9 100644 --- a/packages/yew/src/html/component/scope.rs +++ b/packages/yew/src/html/component/scope.rs @@ -301,29 +301,6 @@ impl Scope { /// synchronously schedules a call to the [Component](Component) /// interface. pub fn callback(&self, function: F) -> Callback - where - M: Into, - F: Fn(IN) -> M + 'static, - { - self.callback_with_passive(None, function) - } - - /// Creates a `Callback` which will send a message to the linked - /// component's update method when invoked. - /// - /// Setting `passive` to [Some] explicitly makes the event listener passive or not. - /// Yew sets sane defaults depending on the type of the listener. - /// See - /// [addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener). - /// - /// Please be aware that currently the result of this callback - /// synchronously schedules a call to the [Component](Component) - /// interface. - pub fn callback_with_passive( - &self, - passive: impl Into>, - function: F, - ) -> Callback where M: Into, F: Fn(IN) -> M + 'static, @@ -333,7 +310,7 @@ impl Scope { let output = function(input); scope.send_message(output); }; - Callback::new(closure, passive.into()) + Callback::from(closure) } /// Creates a `Callback` which will send a batch of messages back diff --git a/packages/yew/src/html/listener/events.rs b/packages/yew/src/html/listener/events.rs index b289b64c4b9..a1b8677f6d6 100644 --- a/packages/yew/src/html/listener/events.rs +++ b/packages/yew/src/html/listener/events.rs @@ -47,8 +47,7 @@ macro_rules! impl_action { } fn passive(&self) -> bool { - let Callback { passive, .. } = &self.callback; - (*passive).unwrap_or($passive) + $passive } } } diff --git a/packages/yew/src/virtual_dom/listeners.rs b/packages/yew/src/virtual_dom/listeners.rs index f6c48e5e30d..4dcd09dca37 100644 --- a/packages/yew/src/virtual_dom/listeners.rs +++ b/packages/yew/src/virtual_dom/listeners.rs @@ -543,10 +543,6 @@ mod tests { } trait Mixin { - fn passive() -> Option { - None - } - fn view(ctx: &Context, state: &State) -> Html where C: Component, @@ -557,8 +553,7 @@ mod tests { } } else { html! { - {state.action} @@ -671,19 +666,6 @@ mod tests { .unwrap(); } - #[test] - async fn passive() { - struct Passive; - - impl Mixin for Passive { - fn passive() -> Option { - Some(true) - } - } - - assert_async::().await; - } - async fn assert_async() { let (link, el) = init::("a"); From 44699af210844f4272471e0fd639437d6d82d240 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 18:18:50 +0500 Subject: [PATCH 4/9] clippy --- examples/function_todomvc/src/hooks/use_bool_toggle.rs | 2 +- packages/yew/src/callback.rs | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/function_todomvc/src/hooks/use_bool_toggle.rs b/examples/function_todomvc/src/hooks/use_bool_toggle.rs index 42662600c70..8bfc00e1403 100644 --- a/examples/function_todomvc/src/hooks/use_bool_toggle.rs +++ b/examples/function_todomvc/src/hooks/use_bool_toggle.rs @@ -52,7 +52,7 @@ pub fn use_bool_toggle(default: bool) -> UseBoolToggleHandle { }; UseBoolToggleHandle { - value: state.clone(), + value: state, toggle, } } diff --git a/packages/yew/src/callback.rs b/packages/yew/src/callback.rs index 75191433561..f2cab2b70a7 100644 --- a/packages/yew/src/callback.rs +++ b/packages/yew/src/callback.rs @@ -44,11 +44,7 @@ impl PartialEq for Callback { impl fmt::Debug for Callback { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let data = match self { - Callback { .. } => "Callback<_>", - }; - - f.write_str(data) + write!(f, "Callback<_>") } } From 82056067719c6828e811cebe95c59d0e3c2d1e24 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 18:23:27 +0500 Subject: [PATCH 5/9] docs --- .../function_todomvc/src/components/entry.rs | 4 ++-- .../src/hooks/use_bool_toggle.rs | 16 ++++++++++------ website/docs/concepts/components/scope.mdx | 13 ++++--------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/examples/function_todomvc/src/components/entry.rs b/examples/function_todomvc/src/components/entry.rs index 18b3f507a17..0cda4da3dd8 100644 --- a/examples/function_todomvc/src/components/entry.rs +++ b/examples/function_todomvc/src/components/entry.rs @@ -1,4 +1,4 @@ -use crate::hooks::use_bool_toggle::{use_bool_toggle, UseBoolToggleHandle}; +use crate::hooks::use_bool_toggle::use_bool_toggle; use crate::state::Entry as Item; use web_sys::{HtmlInputElement, MouseEvent}; use yew::events::{Event, FocusEvent, KeyboardEvent}; @@ -48,7 +48,7 @@ pub fn entry(props: &EntryProps) -> Html { }; let ondblclick = { - let edit_toggle = UseBoolToggleHandle::clone(&edit_toggle); + let edit_toggle = edit_toggle.clone(); move |_| { edit_toggle.clone().toggle(); } diff --git a/examples/function_todomvc/src/hooks/use_bool_toggle.rs b/examples/function_todomvc/src/hooks/use_bool_toggle.rs index 8bfc00e1403..221fe27f363 100644 --- a/examples/function_todomvc/src/hooks/use_bool_toggle.rs +++ b/examples/function_todomvc/src/hooks/use_bool_toggle.rs @@ -35,12 +35,16 @@ impl Deref for UseBoolToggleHandle { /// ... /// let value = use_bool_toggle(false); /// ... -/// /// ... /// ``` pub fn use_bool_toggle(default: bool) -> UseBoolToggleHandle { diff --git a/website/docs/concepts/components/scope.mdx b/website/docs/concepts/components/scope.mdx index 0b070cca9e1..8b60e14cd3a 100644 --- a/website/docs/concepts/components/scope.mdx +++ b/website/docs/concepts/components/scope.mdx @@ -5,7 +5,7 @@ description: "Component's Scope" ## Component's `Scope<_>` API -The component "`Scope`" is the mechanism through which components are able to create callbacks and update themselves +The component "`Scope`" is the mechanism through which components are able to create callbacks and update themselves using messages. We obtain a reference to this by calling `link()` on the context object passed to the component. ### `send_message` @@ -26,8 +26,6 @@ If the given vector is empty, this function doesn't do anything. Create a callback that will send a message to the component when it is executed. Under the hood, it will call `send_message` with the message returned by the provided closure. -There is a different method called `callback_once` which accepts a `FnOnce` instead of a `Fn`. -You should use this with care though, as the resulting callback will panic if executed more than once. ```rust use yew::{html, Component, Context, Html}; @@ -48,16 +46,16 @@ impl Component for Comp { } fn view(&self, ctx: &Context) -> Html { - // Create a callback that accepts some text and sends it + // Create a callback that accepts some text and sends it // to the component as the `Msg::Text` message variant. // highlight-next-line let cb = ctx.link().callback(|text: String| Msg::Text(text)); - + // The previous line is needlessly verbose to make it clearer. // It can be simplified it to this: // highlight-next-line let cb = ctx.link().callback(Msg::Text); - + // Will send `Msg::Text("Hello World!")` to the component. // highlight-next-line cb.emit("Hello World!".to_owned()); @@ -82,6 +80,3 @@ This can be used in cases where, depending on the situation, an update isn't req This is achieved using the `SendAsMessage` trait which is only implemented for these types. You can implement `SendAsMessage` for your own types which allows you to use them in `batch_callback`. - -Like `callback`, this method also has a `FnOnce` counterpart, `batch_callback_once`. -The same restrictions apply as for `callback_once`. From cb9a912a433619b80df4d43caa63335a2be62013 Mon Sep 17 00:00:00 2001 From: Hamza Date: Sun, 26 Dec 2021 18:40:01 +0500 Subject: [PATCH 6/9] make CI happy --- examples/function_todomvc/src/components/entry.rs | 9 +-------- website/docs/concepts/router.mdx | 14 +++++++------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/examples/function_todomvc/src/components/entry.rs b/examples/function_todomvc/src/components/entry.rs index 0cda4da3dd8..d55c477f15f 100644 --- a/examples/function_todomvc/src/components/entry.rs +++ b/examples/function_todomvc/src/components/entry.rs @@ -47,13 +47,6 @@ pub fn entry(props: &EntryProps) -> Html { move |_| onremove.emit(id) }; - let ondblclick = { - let edit_toggle = edit_toggle.clone(); - move |_| { - edit_toggle.clone().toggle(); - } - }; - html! {
  • @@ -63,7 +56,7 @@ pub fn entry(props: &EntryProps) -> Html { checked={props.entry.completed} onclick={ontoggle} /> -