31 releases
new 0.2.4 | Mar 21, 2023 |
---|---|
0.2.3 | Mar 13, 2023 |
0.2.1 | Feb 26, 2023 |
0.1.3 | Jan 28, 2023 |
0.0.11 | Oct 24, 2022 |
#771 in WebAssembly
3,105 downloads per month
Used in 20 crates
(6 directly)
225KB
4.5K
SLoC
The reactive system for the Leptos Web framework.
Fine-Grained Reactivity
Leptos is built on a fine-grained reactive system, which means that individual reactive values (“signals,” sometimes known as observables) trigger the code that reacts to them (“effects,” sometimes known as observers) to re-run. These two halves of the reactive system are inter-dependent. Without effects, signals can change within the reactive system but never be observed in a way that interacts with the outside world. Without signals, effects run once but never again, as there’s no observable value to subscribe to.
Here are the most commonly-used functions and types you'll need to build a reactive system:
Signals
- Signals: create_signal, which returns a (ReadSignal, WriteSignal) tuple, or create_rw_signal, which returns a signal RwSignal without this read-write segregation.
- Derived Signals: any function that relies on another signal.
- Memos: create_memo, which returns a Memo.
- Resources: [create_resource], which converts an
async
[std::future::Future] into a synchronous Resource signal.
Effects
- Use create_effect when you need to synchronize the reactive system with something outside it (for example: logging to the console, writing to a file or local storage)
- The Leptos DOM renderer wraps any [Fn] in your template with create_effect, so components you write do not need explicit effects to synchronize with the DOM.
Example
use leptos_reactive::*;
// creates a new reactive Scope
// this is omitted from most of the examples in the docs
// you usually won't need to call it yourself
create_scope(create_runtime(), |cx| {
// a signal: returns a (getter, setter) pair
let (count, set_count) = create_signal(cx, 0);
// calling the getter gets the value
assert_eq!(count(), 0);
// calling the setter sets the value
set_count(1);
// or we can mutate it in place with update()
set_count.update(|n| *n += 1);
// a derived signal: a plain closure that relies on the signal
// the closure will run whenever we *access* double_count()
let double_count = move || count() * 2;
assert_eq!(double_count(), 4);
// a memo: subscribes to the signal
// the closure will run only when count changes
let memoized_triple_count = create_memo(cx, move |_| count() * 3);
assert_eq!(memoized_triple_count(), 6);
// this effect will run whenever count() changes
create_effect(cx, move |_| {
println!("Count = {}", count());
});
});
Dependencies
~9–16MB
~290K SLoC