Struct leptos_reactive::signal_prelude::prelude::Memo
source · pub struct Memo<T>where
T: 'static,{ /* private fields */ }
Expand description
An efficient derived reactive value based on other reactive values.
Unlike a “derived signal,” a memo comes with two guarantees:
- The memo will only run once per change, no matter how many times you access its value.
- The memo will only notify its dependents if the value of the computation changes.
This makes a memo the perfect tool for expensive computations.
Memos have a certain overhead compared to derived signals. In most cases, you should create a derived signal. But if the derivation calculation is expensive, you should create a memo.
As with create_effect, the argument to the memo function is the previous value,
i.e., the current value of the memo, which will be None
for the initial calculation.
Core Trait Implementations
.get()
(or calling the signal as a function) clones the current value of the signal. If you call it within an effect, it will cause that effect to subscribe to the signal, and to re-run whenever the value of the signal changes..get_untracked()
clones the value of the signal without reactively tracking it.
.with()
allows you to reactively access the signal’s value without cloning by applying a callback function..with_untracked()
allows you to access the signal’s value without reactively tracking it.
.to_stream()
converts the signal to anasync
stream of values.
Examples
let (value, set_value) = create_signal(cx, 0);
// 🆗 we could create a derived signal with a simple function
let double_value = move || value() * 2;
set_value(2);
assert_eq!(double_value(), 4);
// but imagine the computation is really expensive
let expensive = move || really_expensive_computation(value()); // lazy: doesn't run until called
create_effect(cx, move |_| {
// 🆗 run #1: calls `really_expensive_computation` the first time
log::debug!("expensive = {}", expensive());
});
create_effect(cx, move |_| {
// ❌ run #2: this calls `really_expensive_computation` a second time!
let value = expensive();
// do something else...
});
// instead, we create a memo
// 🆗 run #1: the calculation runs once immediately
let memoized = create_memo(cx, move |_| really_expensive_computation(value()));
create_effect(cx, move |_| {
// 🆗 reads the current value of the memo
log::debug!("memoized = {}", memoized());
});
create_effect(cx, move |_| {
// ✅ reads the current value **without re-running the calculation**
let value = memoized();
// do something else...
});
Trait Implementations§
source§impl<T> From<Memo<T>> for MaybeSignal<T>
impl<T> From<Memo<T>> for MaybeSignal<T>
source§impl<T> PartialEq<Memo<T>> for Memo<T>where
T: 'static + PartialEq,
impl<T> PartialEq<Memo<T>> for Memo<T>where T: 'static + PartialEq,
source§impl<T> SignalDispose for Memo<T>
impl<T> SignalDispose for Memo<T>
source§impl<T: Clone> SignalGet<T> for Memo<T>
impl<T: Clone> SignalGet<T> for Memo<T>
Examples
let (count, set_count) = create_signal(cx, 0);
let double_count = create_memo(cx, move |_| count() * 2);
assert_eq!(double_count.get(), 0);
set_count(1);
// double_count() is shorthand for double_count.get()
assert_eq!(double_count(), 2);
source§impl<T: Clone> SignalGetUntracked<T> for Memo<T>
impl<T: Clone> SignalGetUntracked<T> for Memo<T>
source§fn get_untracked(&self) -> T
fn get_untracked(&self) -> T
Gets the signal’s value without creating a dependency on the
current scope. Read more
source§fn try_get_untracked(&self) -> Option<T>
fn try_get_untracked(&self) -> Option<T>
Gets the signal’s value without creating a dependency on the
current scope. Returns [
Some(T)
] if the signal is still
valid, None
otherwise.source§impl<T: Clone> SignalStream<T> for Memo<T>
impl<T: Clone> SignalStream<T> for Memo<T>
source§impl<T> SignalWith<T> for Memo<T>
impl<T> SignalWith<T> for Memo<T>
source§impl<T> SignalWithUntracked<T> for Memo<T>
impl<T> SignalWithUntracked<T> for Memo<T>
impl<T> Copy for Memo<T>
impl<T> Eq for Memo<T>where T: 'static + Eq,
impl<T> StructuralEq for Memo<T>where T: 'static,
impl<T> StructuralPartialEq for Memo<T>where T: 'static,
Auto Trait Implementations§
impl<T> RefUnwindSafe for Memo<T>where T: RefUnwindSafe,
impl<T> Send for Memo<T>where T: Send,
impl<T> Sync for Memo<T>where T: Sync,
impl<T> Unpin for Memo<T>where T: Unpin,
impl<T> UnwindSafe for Memo<T>where T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key
and return true
if they are equal.