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}