chore(react): use effects for event handlers to prevent leaks

This commit is contained in:
Elian Doran
2025-08-25 14:27:32 +03:00
parent 1eaeec8100
commit 72b2a5cc0d

View File

@@ -17,31 +17,35 @@ import { CSSProperties } from "preact/compat";
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) { export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
const parentComponent = useContext(ParentComponent)!; const parentComponent = useContext(ParentComponent)!;
parentComponent.registerHandler(eventName, handler); useEffect(() => {
parentComponent.registerHandler(eventName, handler);
return (() => parentComponent.removeHandler(eventName, handler));
}, []);
useDebugValue(eventName); useDebugValue(eventName);
return (() => parentComponent.removeHandler(eventName, handler));
} }
export function useTriliumEvents<T extends EventNames>(eventNames: T[], handler: (data: EventData<T>, eventName: T) => void) { export function useTriliumEvents<T extends EventNames>(eventNames: T[], handler: (data: EventData<T>, eventName: T) => void) {
const parentComponent = useContext(ParentComponent)!; const parentComponent = useContext(ParentComponent)!;
const handlers: ({ eventName: T, callback: (data: EventData<T>) => void })[] = [];
useDebugValue(() => eventNames.join(", ")); useEffect(() => {
const handlers: ({ eventName: T, callback: (data: EventData<T>) => void })[] = [];
for (const eventName of eventNames) { for (const eventName of eventNames) {
handlers.push({ eventName, callback: (data) => { handlers.push({ eventName, callback: (data) => {
handler(data, eventName); handler(data, eventName);
}}) }})
}
for (const { eventName, callback } of handlers) {
parentComponent.registerHandler(eventName, callback);
}
return (() => {
for (const { eventName, callback } of handlers) {
parentComponent.removeHandler(eventName, callback);
} }
});
for (const { eventName, callback } of handlers) {
parentComponent.registerHandler(eventName, callback);
}
return (() => {
for (const { eventName, callback } of handlers) {
parentComponent.removeHandler(eventName, callback);
}
});
}, []);
useDebugValue(() => eventNames.join(", "));
} }
export function useSpacedUpdate(callback: () => void | Promise<void>, interval = 1000) { export function useSpacedUpdate(callback: () => void | Promise<void>, interval = 1000) {
@@ -202,9 +206,6 @@ export function useNoteContext() {
setNoteContext(noteContext); setNoteContext(noteContext);
setNotePath(noteContext.notePath); setNotePath(noteContext.notePath);
}); });
useTriliumEvent("setNoteContext", ({ noteContext }) => {
setNoteContext(noteContext);
});
useTriliumEvent("noteSwitchedAndActivated", ({ noteContext }) => { useTriliumEvent("noteSwitchedAndActivated", ({ noteContext }) => {
setNoteContext(noteContext); setNoteContext(noteContext);
}); });
@@ -215,6 +216,12 @@ export function useNoteContext() {
setNote(noteContext?.note); setNote(noteContext?.note);
}); });
useLegacyImperativeHandlers({
setNoteContextEvent({ noteContext }: EventData<"setNoteContext">) {
setNoteContext(noteContext);
}
}, true);
useDebugValue(() => `notePath=${notePath}, ntxId=${noteContext?.ntxId}`); useDebugValue(() => `notePath=${notePath}, ntxId=${noteContext?.ntxId}`);
const parentComponent = useContext(ParentComponent) as ReactWrappedWidget; const parentComponent = useContext(ParentComponent) as ReactWrappedWidget;
@@ -506,9 +513,13 @@ export function useTooltip(elRef: RefObject<HTMLElement>, config: Partial<Toolti
return { showTooltip, hideTooltip }; return { showTooltip, hideTooltip };
} }
export function useLegacyImperativeHandlers(handlers: Record<string, Function>) { export function useLegacyImperativeHandlers(handlers: Record<string, Function>, force?: boolean) {
const parentComponent = useContext(ParentComponent); const parentComponent = useContext(ParentComponent);
useEffect(() => { if (!force) {
useEffect(() => {
Object.assign(parentComponent as any, handlers);
}, [ handlers ])
} else {
Object.assign(parentComponent as any, handlers); Object.assign(parentComponent as any, handlers);
}, [ handlers ]) }
} }