From c2316ab8f99bac39bd2020d28fd673a541b42be6 Mon Sep 17 00:00:00 2001 From: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com> Date: Mon, 11 Oct 2021 10:03:15 +0300 Subject: [PATCH 1/3] add set_neq for UseStateHandle --- .../yew/src/functional/hooks/use_state.rs | 12 ++++++ packages/yew/tests/use_state.rs | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/packages/yew/src/functional/hooks/use_state.rs b/packages/yew/src/functional/hooks/use_state.rs index bd6d5b116bf..e320b9f4fa6 100644 --- a/packages/yew/src/functional/hooks/use_state.rs +++ b/packages/yew/src/functional/hooks/use_state.rs @@ -76,9 +76,21 @@ impl fmt::Debug for UseStateHandle { impl UseStateHandle { /// Updates the value + /// + /// *Always causes a rerender* pub fn set(&self, value: T) { (self.setter)(value) } + /// Updates the value if it is different from previous value + pub fn set_neq(&self, value: T) + where + T: PartialEq, + { + if *self.value == value { + return; + } + self.set(value) + } } impl Deref for UseStateHandle { diff --git a/packages/yew/tests/use_state.rs b/packages/yew/tests/use_state.rs index d7430618c0f..b6205950d16 100644 --- a/packages/yew/tests/use_state.rs +++ b/packages/yew/tests/use_state.rs @@ -79,3 +79,40 @@ fn multiple_use_state_setters() { let result = obtain_result(); assert_eq!(result.as_str(), "11"); } + +#[wasm_bindgen_test] +fn use_state_handle_set_neq_works() { + static mut RENDER_COUNT: usize = 0; + + struct UseStateFunction {} + + impl FunctionProvider for UseStateFunction { + type TProps = (); + + fn run(_: &Self::TProps) -> Html { + // No race conditions will be caused since its only used in one place + unsafe { + RENDER_COUNT += 1; + } + let counter = use_state(|| 0); + counter.set_neq(1); + + return html! { +
+ {"Test Output: "} +
{*counter}
+ {"\n"} +
+ }; + } + } + type UseComponent = FunctionComponent; + yew::start_app_in_element::( + yew::utils::document().get_element_by_id("output").unwrap(), + ); + let result = obtain_result(); + assert_eq!(result.as_str(), "1"); + unsafe { + assert_eq!(RENDER_COUNT, 2); + } +} From 337a018db611c2a8da3a289f59c39cee984a15bf Mon Sep 17 00:00:00 2001 From: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com> Date: Mon, 11 Oct 2021 10:08:09 +0300 Subject: [PATCH 2/3] add docs --- website/docs/concepts/function-components/pre-defined-hooks.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/concepts/function-components/pre-defined-hooks.md b/website/docs/concepts/function-components/pre-defined-hooks.md index c1d699c4c3a..625915d6245 100644 --- a/website/docs/concepts/function-components/pre-defined-hooks.md +++ b/website/docs/concepts/function-components/pre-defined-hooks.md @@ -7,7 +7,7 @@ description: "The pre-defined Hooks that Yew comes with " `use_state` is used to manage state in a function component. It returns a `UseState` object which `Deref`s to the current value -and provides a `set` method to update the value. +and provides `set` and `set_neq` methods to update the value. The hook takes a function as input which determines the initial state. This value remains up-to-date on subsequent renders. From c63c5df647a4d9426fec36b837bc3578ec3a1467 Mon Sep 17 00:00:00 2001 From: Julius Lungys <32368314+voidpumpkin@users.noreply.github.com> Date: Wed, 13 Oct 2021 10:26:31 +0300 Subject: [PATCH 3/3] update based on PR comments 1 --- packages/yew/src/functional/hooks/use_state.rs | 8 +++++--- packages/yew/tests/use_state.rs | 2 +- .../concepts/function-components/pre-defined-hooks.md | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/yew/src/functional/hooks/use_state.rs b/packages/yew/src/functional/hooks/use_state.rs index e320b9f4fa6..727a6648801 100644 --- a/packages/yew/src/functional/hooks/use_state.rs +++ b/packages/yew/src/functional/hooks/use_state.rs @@ -75,14 +75,16 @@ impl fmt::Debug for UseStateHandle { } impl UseStateHandle { - /// Updates the value + /// Replaces the value /// /// *Always causes a rerender* pub fn set(&self, value: T) { (self.setter)(value) } - /// Updates the value if it is different from previous value - pub fn set_neq(&self, value: T) + /// Replaces the value if it is different from previous value + /// + /// **Only available for value types that implement PartialEq trait** + pub fn set_if_neq(&self, value: T) where T: PartialEq, { diff --git a/packages/yew/tests/use_state.rs b/packages/yew/tests/use_state.rs index b6205950d16..c3de10416f8 100644 --- a/packages/yew/tests/use_state.rs +++ b/packages/yew/tests/use_state.rs @@ -95,7 +95,7 @@ fn use_state_handle_set_neq_works() { RENDER_COUNT += 1; } let counter = use_state(|| 0); - counter.set_neq(1); + counter.set_if_neq(1); return html! {
diff --git a/website/docs/concepts/function-components/pre-defined-hooks.md b/website/docs/concepts/function-components/pre-defined-hooks.md index 625915d6245..ec064db4f1f 100644 --- a/website/docs/concepts/function-components/pre-defined-hooks.md +++ b/website/docs/concepts/function-components/pre-defined-hooks.md @@ -7,7 +7,8 @@ description: "The pre-defined Hooks that Yew comes with " `use_state` is used to manage state in a function component. It returns a `UseState` object which `Deref`s to the current value -and provides `set` and `set_neq` methods to update the value. +and provides `set` and `set_if_neq` methods to update the value. +Note that `set_if_neq` is only available if your value implements `PartialEq` trait. The hook takes a function as input which determines the initial state. This value remains up-to-date on subsequent renders.