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 an- asyncstream 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§fn from(value: Memo<T>) -> MaybeSignal<T>
 
fn from(value: Memo<T>) -> MaybeSignal<T>
Converts to this type from the input type.
source§impl<T> PartialEq<Memo<T>> for Memo<T>where
    T: PartialEq<T> + 'static,
 
impl<T> PartialEq<Memo<T>> for Memo<T>where T: PartialEq<T> + 'static,
source§impl<T> SignalDispose for Memo<T>
 
impl<T> SignalDispose for Memo<T>
source§impl<T> SignalGet<T> for Memo<T>where
    T: Clone,
 
impl<T> SignalGet<T> for Memo<T>where T: Clone,
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> SignalGetUntracked<T> for Memo<T>where
    T: Clone,
 
impl<T> SignalGetUntracked<T> for Memo<T>where T: Clone,
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> SignalStream<T> for Memo<T>where
    T: Clone,
 
impl<T> SignalStream<T> for Memo<T>where T: Clone,
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: Eq + 'static,
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.