yew_hooks/hooks/
use_previous.rs

1use std::ops::Deref;
2use std::rc::Rc;
3
4use yew::prelude::*;
5
6/// State handle for the [`use_previous`] hook.
7pub struct UsePreviousHandle<T> {
8    inner: Rc<T>,
9}
10
11impl<T> UsePreviousHandle<T> {
12    /// Get the previous immutable ref to state or props.
13    pub fn previous(&self) -> Rc<T> {
14        self.inner.clone()
15    }
16}
17
18impl<T> Deref for UsePreviousHandle<T> {
19    type Target = T;
20
21    fn deref(&self) -> &Self::Target {
22        &self.inner
23    }
24}
25
26impl<T> Clone for UsePreviousHandle<T> {
27    fn clone(&self) -> Self {
28        Self {
29            inner: self.inner.clone(),
30        }
31    }
32}
33
34impl<T> PartialEq for UsePreviousHandle<T>
35where
36    T: PartialEq,
37{
38    fn eq(&self, other: &Self) -> bool {
39        *self.inner == *other.inner
40    }
41}
42
43/// This hook returns the previous immutable ref to state or props.
44///
45/// # Example
46///
47/// ```rust
48/// # use yew::prelude::*;
49/// #
50/// use yew_hooks::prelude::*;
51///
52/// #[function_component(UsePrevious)]
53/// fn previous() -> Html {
54///     let state = use_state(|| 0);
55///     let previous_state = use_previous(state.clone());
56///
57///
58///     let onincrease = {
59///         let state = state.clone();
60///         Callback::from(move |_| state.set(*state + 1))
61///     };
62///     let ondecrease = {
63///         let state = state.clone();
64///         Callback::from(move |_| state.set(*state - 1))
65///     };
66///     
67///     html! {
68///         <div>
69///             <button onclick={onincrease}>{ "Increase" }</button>
70///             <button onclick={ondecrease}>{ "Decrease" }</button>
71///             <p>
72///                 <b>{ "Current value: " }</b>
73///                 { *state }
74///             </p>
75///             <p>
76///                 <b>{ "Previous value: " }</b>
77///                 { **previous_state }
78///             </p>
79///         </div>
80///     }
81/// }
82/// ```
83#[hook]
84pub fn use_previous<T>(value: T) -> UsePreviousHandle<T>
85where
86    T: 'static,
87{
88    let value_rc = Rc::new(value);
89    let state = use_mut_ref(|| value_rc.clone());
90
91    // Update the ref each render so if it changes the newest value will be saved.
92    let inner = state.replace(value_rc);
93
94    UsePreviousHandle { inner }
95}