Expand description
Enables state-like features in functional components.
Hooks
Hooks enable state-like behavior in otherwise functional components. They are heavily inspired by React’s hooks.
The main hooks are:
Using Hooks
Hooks are implemented as traits on the Hooks
provider, which has a primitive use_hook
hook.
In order to use hooks:
- Import the hook’s trait
- Call the function on the
Hooks
provider.- This is implictly introduced into scope as
hooks
when using the#[component(..)]
attribute macro. (See the hooks section of the attribute macro’s documentation).
- This is implictly introduced into scope as
For instance, an example usage of the UseState
and UseEffect
hooks,
use std::{thread, time::Duration};
use intuitive::{
component,
components::{Section, Text},
element::Any as AnyElement,
render,
render::hooks::{UseEffect, UseState},
style::Color,
};
#[component(Root)]
fn render() -> AnyElement {
let seconds = hooks.use_state(|| 0);
// cloned because it's moved into the `use_effect` hook below
let seconds_clone = seconds.clone();
hooks.use_effect(|| {
thread::spawn(move || loop {
thread::sleep(Duration::from_secs(1));
seconds_clone.update(|seconds| seconds + 1).unwrap();
});
});
render! {
Section(title: "Seconds", border: Color::Red) {
Text(text: format!("This program has run for {} seconds", seconds.get()))
}
}
}
Writing Custom Hooks
Custom hooks are, like the built-in hooks, implemented as traits on the Hooks
context provider. For example,
a possible implementation of the UseEffect
hook (without cleanup support, but with dependencies) could be:
pub trait UseEffect {
fn use_effect<D, F>(&mut self, deps: D, func: F)
where
D: 'static + Eq,
F: FnOnce();
}
impl UseEffect for Hooks {
fn use_effect<D, F>(&mut self, deps: D, func: F)
where
D: 'static + Eq,
F: FnOnce(),
{
self.use_memo(deps, func);
}
}
Now, when UseEffect
is imported, UseEffect::use_effect
can be called as a method on Hooks
.
Custom hooks can also rely on Hooks::use_hook
. This is the “primitive” hook that all other hooks must
eventually use in order to hook into the component rendering lifecycle. This is the only hook that is not
implemented as a trait, and is therefore always available.
Modules
Structs
UseEffect
or UseEffectWithDeps
.T
which causes re-renders when mutated, returned by UseState::use_state
.