yew_hooks/hooks/
use_timeout.rs1use std::rc::Rc;
2
3use gloo::timers::callback::Timeout;
4use yew::prelude::*;
5
6use super::{use_mut_latest, use_unmount};
7
8pub struct UseTimeoutHandle {
10 reset: Rc<dyn Fn()>,
11 cancel: Rc<dyn Fn()>,
12}
13
14impl UseTimeoutHandle {
15 pub fn reset(&self) {
17 (self.reset)();
18 }
19
20 pub fn cancel(&self) {
22 (self.cancel)();
23 }
24}
25
26impl Clone for UseTimeoutHandle {
27 fn clone(&self) -> Self {
28 Self {
29 reset: self.reset.clone(),
30 cancel: self.cancel.clone(),
31 }
32 }
33}
34
35#[hook]
76pub fn use_timeout<Callback>(callback: Callback, millis: u32) -> UseTimeoutHandle
77where
78 Callback: FnOnce() + 'static,
79{
80 let callback_ref = use_mut_latest(Some(callback));
81 let timeout_ref = use_mut_ref(|| None);
82
83 let reset = {
84 let timeout_ref = timeout_ref.clone();
85 Rc::new(move || {
86 let timeout_ref = timeout_ref.clone();
87 let callback_ref = callback_ref.clone();
88 if millis > 0 {
89 *timeout_ref.borrow_mut() = Some(Timeout::new(millis, move || {
90 let callback_ref = callback_ref.current();
91 let callback = (*callback_ref.borrow_mut()).take();
92 if let Some(callback) = callback {
93 callback();
94 }
95 }));
96 } else {
97 *timeout_ref.borrow_mut() = None;
98 }
99 })
100 };
101
102 let cancel = {
103 let timeout_ref = timeout_ref.clone();
104 Rc::new(move || {
105 *timeout_ref.borrow_mut() = None;
106 })
107 };
108
109 {
110 let reset = reset.clone();
111 let timeout_ref = timeout_ref.clone();
112 use_effect_with(millis, move |_| {
113 reset();
114
115 move || *timeout_ref.borrow_mut() = None
116 });
117 }
118
119 use_unmount(move || {
120 *timeout_ref.borrow_mut() = None;
121 });
122
123 UseTimeoutHandle { reset, cancel }
124}