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::prelude::*;
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::prelude::*;
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::prelude::*;
let signal = Signal::new(10);
assert_eq!(*signal.get(), 10);Using inside a struct:
use std::rc::Rc;
use reactive_cache::prelude::*;
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");Trait Implementations§
Source§impl<T> SignalSetter<T> for Signal<T>
impl<T> SignalSetter<T> for Signal<T>
Source§default fn set(&self, value: T) -> bool
default fn set(&self, value: T) -> bool
Sets the value of the signal.
For generic types T that do not support comparison, they are treated as
always changing, so the value is always set and true is always returned.
All dependent memos are invalidated and dependent effects were triggered.
§Examples
use reactive_cache::prelude::*;
#[derive(Debug)]
struct Num(i32);
let signal = Signal::new(Num(5));
assert_eq!(signal.set(Num(10)), true);
assert_eq!(signal.get().0, 10);
// Setting to the same value always return true and trigger all effects.
assert_eq!(signal.set(Num(10)), true);Source§impl<T: Eq> SignalSetter<T> for Signal<T>
impl<T: Eq> SignalSetter<T> for Signal<T>
Source§fn set(&self, value: T) -> bool
fn set(&self, value: T) -> bool
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::prelude::*;
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);