From 1b2709f9ebca369a5c7081e5583d39f60c078202 Mon Sep 17 00:00:00 2001 From: Rafi Arrafif Date: Mon, 1 Sep 2025 19:26:24 +0700 Subject: [PATCH] :triangular_flag_on_post: (flags) create run once hooks A custom React hook that ensures a function is executed only once across the entire application, even in React Strict Mode or during development hot reloads. Maintains a global registry to track execution status using a unique key. --- shared/hooks/useRunOnce.debug.ts | 0 shared/hooks/useRunOnce.ts | 42 +++++++++----------------------- 2 files changed, 12 insertions(+), 30 deletions(-) create mode 100644 shared/hooks/useRunOnce.debug.ts diff --git a/shared/hooks/useRunOnce.debug.ts b/shared/hooks/useRunOnce.debug.ts new file mode 100644 index 0000000..e69de29 diff --git a/shared/hooks/useRunOnce.ts b/shared/hooks/useRunOnce.ts index 35205ba..98fe4ca 100644 --- a/shared/hooks/useRunOnce.ts +++ b/shared/hooks/useRunOnce.ts @@ -1,36 +1,18 @@ +"use client"; import { useEffect, useRef } from "react"; -/** - * @module useRunOnce - * @description A custom React hook that ensures a callback function is executed only once - * during the component's lifecycle, even in React Strict Mode or development with hot reloading. - * - * @param {() => void | Promise} callback - The function to execute once. Can be synchronous or asynchronous. - * @returns {void} - * - * @example - * // Synchronous usage - * useRunOnce(() => { - * console.log('This runs only once'); - * initializeSomething(); - * }); - * - * @example - * // Asynchronous usage - * useRunOnce(async () => { - * const data = await fetchData(); - * setInitialData(data); - * }); - */ -const useRunOnce = (callback: () => void | Promise) => { - const calledRef = useRef(false); +const registry = new Set(); + +export function useRunOnce(key: string, fn: () => void) { + const hasRun = useRef(false); useEffect(() => { - if (calledRef.current) return; - calledRef.current = true; + if (hasRun.current) return; + hasRun.current = true; - void callback(); - }, [callback]); -}; + if (registry.has(key)) return; + registry.add(key); -export default useRunOnce; + fn(); + }, [key, fn]); +}