yew_hooks/hooks/
use_raf_state.rs1use std::ops::Deref;
2use std::{cell::RefCell, rc::Rc};
3
4use gloo::render::{request_animation_frame, AnimationFrame};
5use yew::prelude::*;
6
7use super::use_unmount;
8
9pub struct UseRafStateHandle<T> {
11 inner: UseStateHandle<T>,
12 raf: Rc<RefCell<Option<AnimationFrame>>>,
13}
14
15impl<T> UseRafStateHandle<T>
16where
17 T: 'static,
18{
19 pub fn set(&self, value: T) {
21 let inner = self.inner.clone();
22 *self.raf.borrow_mut() = Some(request_animation_frame(move |_| {
23 inner.set(value);
24 }));
25 }
26}
27
28impl<T> Deref for UseRafStateHandle<T> {
29 type Target = T;
30
31 fn deref(&self) -> &Self::Target {
32 &self.inner
33 }
34}
35
36impl<T> Clone for UseRafStateHandle<T> {
37 fn clone(&self) -> Self {
38 Self {
39 inner: self.inner.clone(),
40 raf: self.raf.clone(),
41 }
42 }
43}
44
45impl<T> PartialEq for UseRafStateHandle<T>
46where
47 T: PartialEq,
48{
49 fn eq(&self, other: &Self) -> bool {
50 *self.inner == *other.inner
51 }
52}
53
54#[hook]
90pub fn use_raf_state<T, F>(init_fn: F) -> UseRafStateHandle<T>
91where
92 T: 'static,
93 F: FnOnce() -> T,
94{
95 let inner = use_state(init_fn);
96 let raf = use_mut_ref(|| None);
97
98 {
99 let raf = raf.clone();
100 use_unmount(move || {
101 *raf.borrow_mut() = None;
102 });
103 }
104
105 UseRafStateHandle { inner, raf }
106}