Trait hooks_core::Hook
source · pub trait Hook: HookPollNextUpdate + HookUnmount + for<'hook> HookValue<'hook> {
// Required method
fn use_hook(self: Pin<&mut Self>) -> <Self as HookValue<'_>>::Value;
}Expand description
Defines how to use a hook (get value from the hook).
A hook is something that outputs values reactively.
§How to impl Hook
Usually, you don’t need to impl Hook.
You can easily compose hooks with hook_fn!(...) or
#[hook].
The hook fn actually returns impl UpdateHookUninitialized<Hook = impl Hook>,
so that this hook fn can also be composed in other hook_fn.
For more information, see hook_fn!(...).
§with hook_fn!(...) macro
hook_fn![
pub fn use_my_hook() -> &'hook mut i32 {
let (state, updater) = h![use_shared_set(1)];
state
}
];§with #[hook] attribute macro
/// Print debug on `value` change.
#[hook]
fn use_debug<T: std::fmt::Debug + PartialEq + Copy>(value: T) {
use_effect(|v: &_| {
println!("{v:?}");
}, value);
}§implement Hook manually.
See impl_hook!.
§Comparison with LendingAsyncIterator
A Hook is like a LendingAsyncIterator.
They both produce items asynchronously,
but they have different meanings on pending and terminating:
For pending:
-
If a
LendingAsyncIteratoris pending (poll_nextreturnsPoll::Pending), it is producing the next item. -
If a
Hookis pending, (poll_next_updatereturnsPoll::Pending), it is waiting for its inner state to update. When aHookis pending, the executor can still use it by callinguse_hookand the returned value would remain the same as the last returned value. Using a hook is like inspecting it. Some hooks may do heavy work inuse_hook. It is advised to calluse_hookonly afterpoll_next_updatereturnsPoll::Ready(true).
For terminating:
-
If a
LendingAsyncIteratoris terminated (poll_nextreturnsPoll::Ready(None)), the executor MUST NOT callpoll_nextagain. -
There is no termination for a
Hookuntil dropped. Whenpoll_next_updatereturnsPoll::Ready(false), this means the hook is no longer dynamic (its inner state will no longer update). Thus, there is no need to calluse_hookagain because the returned value is expected to remain the same. But the executor can still calluse_hookto re-get the value or update it withupdate_hookorh, and this might make the hook dynamic again.This behavior makes it possible to combine multiple hooks. When some hooks are no longer dynamic but other hooks depend on their returned values, the executor can still get the values from the no-longer-dynamic hooks, and pass the values to the dynamic hooks.
Also see NonLendingHook for a subset of hooks that doesn’t lend lifetimes to values,
which are like AsyncIterator or Stream.