Function leptos::create_owning_memo

source ·
pub fn create_owning_memo<T>(
    f: impl Fn(Option<T>) -> (T, bool) + 'static
) -> Memo<T>
where T: 'static,
Expand description

Like create_memo, create_owning_memo creates an efficient derived reactive value based on other reactive values, but with two differences:

  1. The argument to the memo function is owned instead of borrowed.
  2. The function must also return whether the value has changed, as the first element of the tuple.

All of the other caveats and guarantees are the same as the usual “borrowing” memos.

This type of memo is useful for memos which can avoid computation by re-using the last value, especially slices that need to allocate.

pub struct State {
    name: String,
    token: String,
}

let state = create_rw_signal(State {
    name: "Alice".to_owned(),
    token: "abcdef".to_owned(),
});

// If we used `create_memo`, we'd need to allocate every time the state changes, but by using
// `create_owning_memo` we can allocate only when `state.name` changes.
let name = create_owning_memo(move |old_name| {
    state.with(move |state| {
        if let Some(name) =
            old_name.filter(|old_name| old_name == &state.name)
        {
            (name, false)
        } else {
            (state.name.clone(), true)
        }
    })
});
let set_name = move |name| state.update(|state| state.name = name);

// We can also re-use the last allocation even when the value changes, which is usually faster,
// but may have some caveats (e.g. if the value size is drastically reduced, the memory will
// still be used for the life of the memo).
let token = create_owning_memo(move |old_token| {
    state.with(move |state| {
        let is_different = old_token.as_ref() != Some(&state.token);
        let mut token = old_token.unwrap_or_else(String::new);

        if is_different {
            token.clone_from(&state.token);
        }
        (token, is_different)
    })
});
let set_token = move |new_token| state.update(|state| state.token = new_token);