The reactive_graph crate implements a fine-grained reactive system using three core primitives. This approach models data flow by composing these units, ensuring that updates to a signal only trigger the specific computations or effects that depend on it, avoiding unnecessary diffing.
Core Primitives
- Signals: Atomic units of state that can be directly mutated (e.g.,
ArcRwSignal). They act as "source" nodes. - Computations: Derived values that cannot be mutated directly but update automatically when their dependencies change (e.g.,
ArcMemo). They act as both "source" nodes (for others to subscribe to) and "subscriber" nodes. - Effects: Side effects used to synchronize the reactive system with the outside world (e.g.,
Effect). They act as "subscriber" nodes.
Key Characteristics
- Dynamic Dependency Tracking: Dependencies are tracked at runtime rather than being declared statically. If a computation contains conditional logic, it will only subscribe to the dependencies used in the currently active branch. Subscribers automatically unsubscribe from unused dependencies between runs.
- Asynchronous Effect Scheduling: While updating a signal changes its value immediately, dependent
Effects are scheduled as asynchronous tasks. They run during the next "tick" of the async runtime. This makes the library async runtime agnostic (compatible with tokio, wasm-bindgen-futures, glib, etc.). - Efficiency Focus: The system is optimized to minimize the execution of effects (which are assumed to be expensive) at the cost of a small amount of raw update speed for signal propagation.
use reactive_graph::{
computed::ArcMemo,
effect::Effect,
prelude::{Read, Set},
signal::ArcRwSignal,
};
let count = ArcRwSignal::new(1);
let double_count = ArcMemo::new({
let count = count.clone();
move |_| *count.read() * 2
});
// the effect will run once initially
Effect::new(move |_| {
println!("double_count = {}", *double_count.read());
});
// updating `count` will propagate changes to the dependencies,
// causing the effect to run again
count.set(2);