pub struct Signal<T> { /* private fields */ }Expand description
A reactive signal that holds a value, tracks dependencies, and triggers effects.
Signal<T> behaves similarly to a traditional “Property” (getter/setter),
but on top of that, it automatically tracks which reactive computations
or effects access it. When its value changes, all dependent effects
are automatically re-run.
In short:
- Like a Property: provides
get()andset()for accessing and updating the value. - Adds tracking: automatically records dependencies when read inside reactive contexts,
and automatically triggers dependent
Effects when updated.
§Type Parameters
T: The type of the value stored in the signal. Must implementEq.
§Memory Management Note
When referencing Signal instances that belong to other struct instances
(for example, when one ViewModel holds references to signals in another ViewModel),
you must store them as Weak<Signal<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;
let signal = Signal::new(10);
assert_eq!(*signal.get(), 10);
signal.set(20);
assert_eq!(*signal.get(), 20);§Using inside a struct
use std::rc::Rc;
use reactive_cache::Signal;
struct ViewModel {
counter: Rc<Signal<i32>>,
name: Rc<Signal<String>>,
}
let vm = ViewModel {
counter: Signal::new(0).into(),
name: Signal::new("Alice".to_string()).into(),
};
assert_eq!(*vm.counter.get(), 0);
assert_eq!(*vm.name.get(), "Alice");
vm.counter.set(1);
vm.name.set("Bob".into());
assert_eq!(*vm.counter.get(), 1);
assert_eq!(*vm.name.get(), "Bob");Implementations§
Source§impl<T> Signal<T>
impl<T> Signal<T>
Sourcepub fn new(value: T) -> Rc<Self>
pub fn new(value: T) -> Rc<Self>
Creates a new Signal with the given initial value.
§Examples
Basic usage:
use std::rc::Rc;
use reactive_cache::Signal;
let signal = Signal::new(10);
assert_eq!(*signal.get(), 10);Using inside a struct:
use std::rc::Rc;
use reactive_cache::Signal;
struct ViewModel {
counter: Rc<Signal<i32>>,
name: Rc<Signal<String>>,
}
let vm = ViewModel {
counter: Signal::new(0),
name: Signal::new("Alice".to_string()),
};
assert_eq!(*vm.counter.get(), 0);
assert_eq!(*vm.name.get(), "Alice");
// Update values
assert!(vm.counter.set(1));
assert!(vm.name.set("Bob".into()));
assert_eq!(*vm.counter.get(), 1);
assert_eq!(*vm.name.get(), "Bob");Sourcepub fn get(&self) -> Ref<'_, T>
pub fn get(&self) -> Ref<'_, T>
Gets a reference to the current value, tracking dependencies and effects if inside a reactive context.
§Examples
use reactive_cache::Signal;
let signal = Signal::new(42);
assert_eq!(*signal.get(), 42);Sourcepub fn set(&self, value: T) -> boolwhere
T: Eq,
pub fn set(&self, value: T) -> boolwhere
T: Eq,
Sets the value of the signal.
Returns true if the value changed, all dependent memos are
invalidated and dependent effects were triggered.
§Examples
use reactive_cache::Signal;
let signal = Signal::new(5);
assert_eq!(signal.set(10), true);
assert_eq!(*signal.get(), 10);
// Setting to the same value returns false
assert_eq!(signal.set(10), false);