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}