commit 422aee9e959247af4df4938984a36e8ca2ad07eb
parent 4f1f0d96fc3ad5061b610c3075262b00332e1d0d
Author: Sebastian <sebasjm@gmail.com>
Date: Mon, 20 Jan 2025 02:20:17 -0300
on component unload should be in web utils
Diffstat:
2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/packages/web-util/src/components/index.ts b/packages/web-util/src/components/index.ts
@@ -1,4 +1,5 @@
export * as utils from "./utils.js";
+export { onComponentUnload } from "./utils.js";
export * from "./Attention.js";
export * from "./CopyButton.js";
export * from "./ErrorLoading.js";
diff --git a/packages/web-util/src/components/utils.ts b/packages/web-util/src/components/utils.ts
@@ -1,4 +1,5 @@
import { createElement, VNode } from "preact";
+import { useEffect, useRef } from "preact/hooks";
export type StateFunc<S> = (p: S) => VNode;
@@ -12,7 +13,6 @@ export function compose<SType extends { status: string }, PType>(
hook: (p: PType) => RecursiveState<SType>,
viewMap: StateViewMap<SType>,
): (p: PType) => VNode {
-
function withHook(stateHook: () => RecursiveState<SType>): () => VNode {
function ComposedComponent(): VNode {
const state = stateHook();
@@ -39,7 +39,6 @@ export function compose<SType extends { status: string }, PType>(
export function recursive<PType>(
hook: (p: PType) => RecursiveState<VNode>,
): (p: PType) => VNode {
-
function withHook(stateHook: () => RecursiveState<VNode>): () => VNode {
function ComposedComponent(): VNode {
const state = stateHook();
@@ -61,7 +60,28 @@ export function recursive<PType>(
};
}
-
+/**
+ * Call `callback` only once.
+ *
+ * Callback can be a closure with binding to the current caller context. This helper
+ * will always take the latest `callback`
+ *
+ * @param callback
+ */
+export function onComponentUnload(callback: () => void) {
+ /**
+ * we use a ref to avoid evaluating the effect function
+ * on every render and so the unload is called only once
+ */
+ const ref = useRef<typeof callback>();
+ ref.current = callback;
+
+ useEffect(() => {
+ return () => {
+ ref.current!();
+ };
+ }, []);
+}
/**
*