-
-
Notifications
You must be signed in to change notification settings - Fork 0
Hooks
defineHook({ name?, layers?, setup })Status: Current.
Hooks package reusable reactive logic. Component and hook layer access uses the same alias-record model.
export const useCurrentUser = defineHook({
name: 'useCurrentUser',
layers: { auth: AuthLayer } as const,
setup({ computed, layers }) {
const auth = layers.auth.service('auth');
return {
label: computed(() => auth.currentUser().name),
};
},
});The layer must already be registered at the application composition root. Missing bindings fail before hook setup executes.
| Member | Purpose |
|---|---|
config |
Typed input supplied by the caller. |
signal, computed
|
Reactive state and derivation. |
watchEffect |
Lifecycle-owned reactive effect with rerun cleanup and an EffectHandle. |
onMount |
Register work with an active component lifecycle. |
layers |
Typed alias or list accessor. |
scope |
Register LIFO finalizers or manually dispose a standalone hook. |
use |
Compose another hook function. |
runAsync |
Execute typed asynchronous work. |
const useThreshold = defineHook<
{ minimum: number },
{ accepted: (value: number) => boolean }
>({
setup({ config }) {
return { accepted: (value) => value >= config.minimum };
},
});Hooks called during component setup are owned by that component lifecycle.
Unmount stops every hook effect synchronously before asynchronous scope
finalizers run. A cleanup returned from watchEffect runs before the next
reactive execution and again when the effect stops:
const useWindowEvents = defineHook({
setup({ watchEffect }) {
const effect = watchEffect(() => {
const onResize = () => console.log(window.innerWidth);
window.addEventListener('resize', onResize);
return () => window.removeEventListener('resize', onResize);
});
return { pause: effect.pause, resume: effect.resume };
},
});Use scope.addFinalizer for a resource that must survive effect reruns and end
only when the hook is disposed. Finalizers execute once in reverse registration
order. Every finalizer is attempted; multiple failures are combined and routed
through the lifecycle error handler.
When a hook is invoked without an active component lifecycle, onMount runs
immediately and its cleanup belongs to the hook scope. A standalone hook must
expose or otherwise arrange scope.dispose() if it allocates long-lived
resources. Component-owned hooks need no manual disposal.
If layer validation or hook setup throws, Effuse stops effects immediately, starts best-effort scope cleanup, preserves the original setup error, and reports any asynchronous rollback failure as a lifecycle cleanup error.
@effuse/use provides browser-focused hooks for storage, media queries, online
state, intervals, debounce/throttle, event listeners, element visibility,
window size, and related concerns. Browser-only hooks must retain explicit SSR
guards.