yew_hooks/hooks/use_debounce_effect.rs
1use yew::prelude::*;
2
3use super::{use_debounce, use_unmount};
4
5/// A hook that delays calling effect callback until after wait milliseconds have elapsed
6/// since the last time effect callback was called.
7///
8/// # Example
9///
10/// ```rust
11/// # use web_sys::HtmlInputElement;
12/// # use yew::prelude::*;
13/// #
14/// use yew_hooks::prelude::*;
15///
16/// #[function_component(DebounceEffect)]
17/// fn debounce_effect() -> Html {
18/// let status = use_state(|| "Typing stopped".to_string());
19/// let value = use_state(|| "".to_string());
20/// let debounced_value = use_state(|| "".to_string());
21///
22/// {
23/// let status = status.clone();
24/// let value = value.clone();
25/// let debounced_value = debounced_value.clone();
26/// use_debounce_effect(
27/// move || {
28/// // This will delay updating state.
29/// debounced_value.set((*value).clone());
30/// status.set("Typing stopped".to_string());
31/// },
32/// 2000,
33/// );
34/// }
35///
36/// let oninput = {
37/// let status = status.clone();
38/// let value = value.clone();
39/// Callback::from(move |e: InputEvent| {
40/// let input: HtmlInputElement = e.target_unchecked_into();
41/// // This will update state every time.
42/// value.set(input.value());
43/// status.set("Waiting for typing to stop...".to_string());
44/// })
45/// };
46///
47/// html! {
48/// <>
49/// <input type="text" value={(*value).clone()} placeholder="Debounced input" {oninput}/>
50/// <p>{&*status}</p>
51/// <p>
52/// <b>{ "Value: " }</b> {&*value}
53/// </p>
54/// <p>
55/// <b>{ "Debounced value: " }</b> {&*debounced_value}
56/// </p>
57/// </>
58/// }
59/// }
60/// ```
61#[hook]
62pub fn use_debounce_effect<Callback>(callback: Callback, millis: u32)
63where
64 Callback: FnOnce() + 'static,
65{
66 let debounce = use_debounce(callback, millis);
67
68 {
69 let debounce = debounce.clone();
70 use_effect(move || {
71 debounce.run();
72
73 || ()
74 });
75 }
76
77 use_unmount(move || {
78 debounce.cancel();
79 });
80}
81
82/// This hook is similar to [`use_debounce_effect`] but it accepts dependencies.
83///
84/// Whenever the dependencies are changed, the debounce effect is run again.
85/// To detect changes, dependencies must implement `PartialEq`.
86#[hook]
87pub fn use_debounce_effect_with_deps<Callback, Dependents>(
88 callback: Callback,
89 millis: u32,
90 deps: Dependents,
91) where
92 Callback: FnOnce() + 'static,
93 Dependents: PartialEq + 'static,
94{
95 let debounce = use_debounce(callback, millis);
96
97 {
98 let debounce = debounce.clone();
99 use_effect_with(deps, move |_| {
100 debounce.run();
101
102 || ()
103 });
104 }
105
106 use_unmount(move || {
107 debounce.cancel();
108 });
109}