From 5a17075eef907fecc969633b161c53b81dbb0855 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 24 Aug 2025 22:21:11 +0300 Subject: [PATCH] refactor(react/ribbon): use effects for event handling --- apps/client/src/widgets/react/hooks.tsx | 54 ++++++++++++++++--------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 8071c962e..aa75ea61b 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -15,31 +15,49 @@ import { RefObject, VNode } from "preact"; import { Tooltip } from "bootstrap"; import { CSSProperties } from "preact/compat"; +/** + * Allows a React component to listen to Trilium's legacy event system. + * + * The handler works by registering the event listener on the parent legacy component. + * + * @param eventName the event to listen on. + * @param handler the callback to be invoked when the event is triggered. + */ export function useTriliumEvent(eventName: T, handler: (data: EventData) => void) { const parentComponent = useContext(ParentComponent)!; - parentComponent.registerHandler(eventName, handler); - return (() => parentComponent.removeHandler(eventName, handler)); + useEffect(() => { + parentComponent.registerHandler(eventName, handler); + return (() => parentComponent.removeHandler(eventName, handler)); + }, [ eventName, handler, parentComponent ]) } +/** + * Similar to {@link useTriliumEvent}, but listens to multiple events at once. + * + * @param eventNames the events to listen on. + * @param handler the callback to be invoked when one of the events is triggered. The name of the event is provided as the second argument. + */ export function useTriliumEvents(eventNames: T[], handler: (data: EventData, eventName: T) => void) { const parentComponent = useContext(ParentComponent)!; - const handlers: ({ eventName: T, callback: (data: EventData) => void })[] = []; - - for (const eventName of eventNames) { - handlers.push({ eventName, callback: (data) => { - handler(data, eventName); - }}) - } - - for (const { eventName, callback } of handlers) { - parentComponent.registerHandler(eventName, callback); - } - - return (() => { - for (const { eventName, callback } of handlers) { - parentComponent.removeHandler(eventName, callback); + useEffect(() => { + const handlers: ({ eventName: T, callback: (data: EventData) => void })[] = []; + + for (const eventName of eventNames) { + handlers.push({ eventName, callback: (data) => { + handler(data, eventName); + }}) } - }); + + for (const { eventName, callback } of handlers) { + parentComponent.registerHandler(eventName, callback); + } + + return (() => { + for (const { eventName, callback } of handlers) { + parentComponent.removeHandler(eventName, callback); + } + }); + }, [ eventNames, handler, parentComponent ]); } export function useSpacedUpdate(callback: () => void | Promise, interval = 1000) {