import { useCallback, useEffect, useRef } from "react"; import type { TAction, TActionFunc, TActionHandlerOptions, TArgOfAction, TInvocationTrigger, } from "@/actions"; import { bindAction, unbindAction } from "@/actions"; // eslint-disable-next-line opencut/prefer-object-params -- action subscriptions read best as (action, handler, isActive). export function useActionHandler( action: A, handler: TActionFunc, isActive: TActionHandlerOptions, ) { const handlerRef = useRef>(handler); const isBoundRef = useRef(false); useEffect(() => { handlerRef.current = handler; }, [handler]); const stableHandler = useCallback( (...parameters: [TArgOfAction, TInvocationTrigger?]) => { ( handlerRef.current as ( ...handlerParameters: [TArgOfAction, TInvocationTrigger?] ) => void )(...parameters); }, [], ) as TActionFunc; useEffect(() => { const shouldBind = isActive === undefined || (typeof isActive === "boolean" ? isActive : isActive.current); if (shouldBind && !isBoundRef.current) { bindAction(action, stableHandler); isBoundRef.current = true; } else if (!shouldBind && isBoundRef.current) { unbindAction(action, stableHandler); isBoundRef.current = false; } return () => { unbindAction(action, stableHandler); isBoundRef.current = false; }; }, [action, stableHandler, isActive]); }