Skip to content

Commit

Permalink
Add set_if_neq for UseStateHandle (yewstack#2109)
Browse files Browse the repository at this point in the history
* add set_neq for UseStateHandle

* add docs

* update based on PR comments 1
  • Loading branch information
voidpumpkin authored Oct 15, 2021
1 parent 5b7d009 commit f2a0d61
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
16 changes: 15 additions & 1 deletion packages/yew/src/functional/hooks/use_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,24 @@ impl<T: fmt::Debug> fmt::Debug for UseStateHandle<T> {
}

impl<T> UseStateHandle<T> {
/// Updates the value
/// Replaces the value
///
/// *Always causes a rerender*
pub fn set(&self, value: T) {
(self.setter)(value)
}
/// 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,
{
if *self.value == value {
return;
}
self.set(value)
}
}

impl<T> Deref for UseStateHandle<T> {
Expand Down
37 changes: 37 additions & 0 deletions packages/yew/tests/use_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_if_neq(1);

return html! {
<div>
{"Test Output: "}
<div id="result">{*counter}</div>
{"\n"}
</div>
};
}
}
type UseComponent = FunctionComponent<UseStateFunction>;
yew::start_app_in_element::<UseComponent>(
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 a `set` method 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.
Expand Down

0 comments on commit f2a0d61

Please sign in to comment.