Local state for Seed web apps
seed_hooks is a crate that allows you to store state on a per component basis in your seed apps. It is designed as a clone of React Hooks, principally the useState hook.
Here a component is defined as a 'topological aware execution context', this means that the component is aware of its own call-site identity and location in the call tree.
Example:
This is a complete counting button with state implemented in in the Seed framework:
use seed_hooks::*;
#[topo::nested]
fn my_button() -> Node<Msg> {
let count = use_state(|| 0);
div![
count.get(),
button![count.mouse_ev(Ev::Click, |count, _| *count += 1), "Click me"],
]
}
The two most important functions are:
#[topo::nested]
function annotation defines the a topologically aware function. EverythingHow does it work?
this relies on the #![feature(track_caller)]
feature gate to be enabled.
topo creates a new execution context for every #[topo::nested]
function or every topo::call
block. The outermost call
re-roots the execution context. The re-rooting allows for consistent
execution contexts for the same components as long as you re-root at the start of the
base view function. This means that one can store and retrieve local data for an
individual component annotated by #[topo::nested]
.
The execution context is not only determined by the order of calling a functions but also the source location of these calls. This means that state is consistent and stable even though branching logic might call topologically aware functions in different orders.
See this awesome talk explaining how topo works: https://www.youtube.com/watch?v=tmM756XZt20
a type gets stored with : let my_string = use_state(||"text")
which stores "text"
in the component for the str
type. This returns a
state accessor struct responsible for getting and setting of the state.
The accessor is useful because it can be passed to callbacks or cloned or called from
different topological contexts. i.e. my_string.(new_text)
will work no matter
where it is called.
currently seed_hooks exposes a clone to stored values via get()
and to non-Clone types with get_with()
seed_hooks is a Seed specific wrapper around the atomic_hooks crate.