Skip to main content

rosace_core/
lifecycle.rs

1use crate::context::Context;
2
3/// Runs `f` exactly once when the component first mounts, and registers the
4/// returned cleanup function to run exactly once when the component unmounts.
5///
6/// This is idempotent: if `build()` is called multiple times (once per frame),
7/// the setup runs only on the first call thanks to persistent hook state.
8pub fn on_mount<F, Cleanup>(ctx: &mut Context, f: F)
9where
10    F: FnOnce() -> Cleanup + Send + 'static,
11    Cleanup: FnOnce() + Send + 'static,
12{
13    let already_mounted = ctx.state(false);
14    if !already_mounted.get() {
15        already_mounted.set(true);
16        let cleanup = f();
17        ctx.on_cleanup(cleanup);
18    }
19}
20
21/// Registers `f` to run exactly once when the component unmounts.
22///
23/// Idempotent: repeated calls from the same hook slot (across frames) register
24/// the cleanup only on first call.
25pub fn on_unmount(ctx: &mut Context, f: impl FnOnce() + Send + 'static) {
26    let already_registered = ctx.state(false);
27    if !already_registered.get() {
28        already_registered.set(true);
29        ctx.on_cleanup(f);
30    }
31}