This is unreleased documentation for Yew Next version.
For up-to-date documentation, see the latest version on docs.rs.

yew/functional/hooks/
use_memo.rs

1use std::borrow::Borrow;
2use std::rc::Rc;
3
4use super::use_mut_ref;
5use crate::functional::hook;
6
7/// Get a immutable reference to a memoized value.
8///
9/// This version allows for a key cache key derivation that only borrows
10/// like the original argument. For example, using ` K = Rc<D>`, we only
11/// create a shared reference to dependencies *after* they change.
12#[hook]
13pub(crate) fn use_memo_base<T, F, D, K>(f: F, deps: D) -> Rc<T>
14where
15    T: 'static,
16    F: FnOnce(D) -> (T, K),
17    K: 'static + Borrow<D>,
18    D: PartialEq,
19{
20    struct MemoState<T, K> {
21        memo_key: K,
22        result: Rc<T>,
23    }
24    let state = use_mut_ref(|| -> Option<MemoState<T, K>> { None });
25
26    let mut state = state.borrow_mut();
27    match &*state {
28        Some(existing) if existing.memo_key.borrow() != &deps => {
29            // Drop old state if it's outdated
30            *state = None;
31        }
32        _ => {}
33    };
34    let state = state.get_or_insert_with(|| {
35        let (result, memo_key) = f(deps);
36        let result = Rc::new(result);
37        MemoState { result, memo_key }
38    });
39    state.result.clone()
40}
41
42/// Get a immutable reference to a memoized value.
43///
44/// Memoization means it will only get recalculated when provided dependencies update/change.
45///
46/// It can be useful for keeping things in scope for the lifetime of the component,
47/// so long as you don't store a clone of the resulting `Rc` anywhere that outlives the component.
48///
49/// # Example
50///
51/// ```rust
52/// use yew::prelude::*;
53///
54/// #[derive(PartialEq, Properties)]
55/// pub struct Props {
56///     pub step: usize,
57/// }
58///
59/// #[function_component(UseMemo)]
60/// fn memo(props: &Props) -> Html {
61///     // Will only get recalculated if `props.step` value changes
62///     let message = use_memo(props.step, |step| {
63///         format!("{}. Do Some Expensive Calculation", step)
64///     });
65///
66///     html! {
67///         <div>
68///             <span>{ (*message).clone() }</span>
69///         </div>
70///     }
71/// }
72/// ```
73#[hook]
74pub fn use_memo<T, F, D>(deps: D, f: F) -> Rc<T>
75where
76    T: 'static,
77    F: FnOnce(&D) -> T,
78    D: 'static + PartialEq,
79{
80    use_memo_base(|d| (f(&d), d), deps)
81}