unexpected behavior of use_debounce
It seems that use_debounce returns a callback in a triggered state. That is, after the given time elapses the original callback is invoked whether or not the debounced version was ever invoked. This is not the behavior that I would expect. Is this the desired behavior for this hook?
The following code demonstrates:
use gloo_console::log;
use yew::prelude::*;
use yew_hooks::use_debounce;
#[function_component(App)]
fn app() -> Html {
let f = use_debounce(|| {
log!("this should never print, but it does");
}, 1000);
html! {}
}
fn main() {
yew::Renderer::<App>::new().render();
}
Yes, this is definitely a bug, because use_debounce calls use_timeout directly, which:
- runs its callback unconditionally,
- takes a
FnOnce()which only runs once.
From FnOnce docs from rustlib/src/rust/library/core/src/ops/function.rs:
/// Instances of `FnOnce` can be called, but might not be callable multiple
/// times. Because of this, if the only thing known about a type is that it
/// implements `FnOnce`, it can only be called once.
I've managed to fix these issues and will do a PR. use_debounce should not rely on use_timeout if use_timeout should, by definition, only run once, and doesn't have any dependencies that could cause it to be called again.
hi @tgrushka , could you try the demo here: https://jetli.github.io/yew-hooks/#/use_debounce? I think the current implementation is expected, often used in scenarios like typing and searching which prevents too many requests to servers. the callback is invoked by default without .run() which is by design, and call .run() to invoke again. the implementation is inspired by this react hook: https://github.com/streamich/react-use/blob/master/src/useDebounce.ts, which uses timeout too. may be we can add another use_debounce_with_deps or something to provide deps.