Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add set_if_neq for UseStateHandle #2109

Merged
merged 3 commits into from
Oct 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
}
mc1098 marked this conversation as resolved.
Show resolved Hide resolved
}

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