pub struct Memo<T> { /* private fields */ }Expand description
A memoized reactive computation that caches its result and tracks dependencies.
Memo<T> behaves similarly to a computed property: it stores the result of a closure
and only recomputes when its dependencies change. Other signals or effects that access
the memo will automatically be tracked.
In short:
- Like a computed property: returns a cached value derived from other signals.
- Adds tracking: recomputes only when dependencies are invalidated.
§Type Parameters
T: The result type of the computation. Must implementClone.
§Memory Management Note
When referencing Memo instances that belong to other struct instances
(for example, when one ViewModel holds references to memos in another ViewModel),
you must store them as Weak<Memo<T>> obtained via Rc::downgrade instead of
cloning a strong Rc. Failing to do so can create reference cycles between the structs
and their dependent effects, preventing proper cleanup and causing memory leaks.
§Examples
§Basic usage
use std::rc::Rc;
use reactive_cache::{Signal, Memo};
let counter = Signal::new(1);
let double = {
let counter = Rc::clone(&counter);
Memo::new({
let counter = Rc::new(counter);
move || *counter.get() * 2
})
};
assert_eq!(double.get(), 2);
counter.set(3);
assert_eq!(double.get(), 6);§Using inside a struct
use std::rc::Rc;
use reactive_cache::{Signal, Memo};
struct ViewModel {
counter: Rc<Signal<i32>>,
double: Rc<Memo<i32>>,
}
let counter = Signal::new(1);
let double = Memo::new({
let counter = counter.clone();
move || *counter.get() * 2
});
let vm = ViewModel { counter, double };
assert_eq!(vm.double.get(), 2);
vm.counter.set(4);
assert_eq!(vm.double.get(), 8);Implementations§
Source§impl<T> Memo<T>
impl<T> Memo<T>
Sourcepub fn new(f: impl Fn() -> T + 'static) -> Rc<Self>where
T: 'static,
pub fn new(f: impl Fn() -> T + 'static) -> Rc<Self>where
T: 'static,
Creates a new Memo wrapping the provided closure.
§Requirements
Tmust be'static, because the value is stored in global cache.- The closure must be
'staticas well.
§Examples
Basic usage:
use reactive_cache::Memo;
let memo = Memo::new(|| 10);
assert_eq!(memo.get(), 10);Using inside a struct:
use std::rc::Rc;
use reactive_cache::{Signal, Memo};
struct ViewModel {
a: Rc<Signal<i32>>,
b: Rc<Signal<i32>>,
sum: Rc<Memo<i32>>,
}
// Construct signals
let a = Signal::new(2);
let b = Signal::new(3);
// Construct a memo depending on `a` and `b`
let sum = {
let a = a.clone();
let b = b.clone();
Memo::new(move || {
// `Signal::get()` will register dependencies automatically
*a.get() + *b.get()
})
};
let vm = ViewModel { a, b, sum };
// Initial computation
assert_eq!(vm.sum.get(), 5);
// Update a signal → memo recomputes
vm.a.set(10);
assert_eq!(vm.sum.get(), 13);