diff --git a/src/hooks/useMenuEvents.editorFind.test.ts b/src/hooks/useMenuEvents.editorFind.test.ts index c291c1c1..a7ed2caa 100644 --- a/src/hooks/useMenuEvents.editorFind.test.ts +++ b/src/hooks/useMenuEvents.editorFind.test.ts @@ -70,4 +70,21 @@ describe('useMenuEvents editor find state', () => { })) }) }) + + it('does not resync native menu state for equivalent rerenders', async () => { + const { rerender } = renderHook( + ({ handlers }: { handlers: MenuEventHandlers }) => useMenuEvents(handlers), + { initialProps: { handlers: makeHandlers() } }, + ) + await vi.dynamicImportSettled() + + expect(invokeMock).toHaveBeenCalledTimes(1) + invokeMock.mockClear() + + rerender({ handlers: makeHandlers() }) + rerender({ handlers: makeHandlers() }) + await vi.dynamicImportSettled() + + expect(invokeMock).not.toHaveBeenCalled() + }) }) diff --git a/src/hooks/useMenuEvents.ts b/src/hooks/useMenuEvents.ts index 656d72fd..9b9848ee 100644 --- a/src/hooks/useMenuEvents.ts +++ b/src/hooks/useMenuEvents.ts @@ -1,4 +1,4 @@ -import { useEffect, useRef, useState } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { isTauri } from '../mock-tauri' import { APP_COMMAND_EVENT_NAME, @@ -184,6 +184,23 @@ export function useMenuEvents(handlers: MenuEventHandlers) { const hasConflicts = handlers.conflictCount != null ? handlers.conflictCount > 0 : undefined const hasRestorableDeletedNote = handlers.hasRestorableDeletedNote const hasNoRemote = handlers.hasNoRemote + const menuState = useMemo(() => ({ + hasActiveNote, + hasModifiedFiles, + hasConflicts, + hasRestorableDeletedNote, + hasNoRemote, + noteListSearchEnabled, + editorFindEnabled, + }), [ + hasActiveNote, + hasModifiedFiles, + hasConflicts, + hasRestorableDeletedNote, + hasNoRemote, + noteListSearchEnabled, + editorFindEnabled, + ]) useEffect(() => { ref.current = handlers @@ -192,13 +209,5 @@ export function useMenuEvents(handlers: MenuEventHandlers) { useNativeMenuEventListener(ref) useWindowAppCommandListener(ref) useTestMenuCommandBridge(ref) - useNativeMenuStateSync({ - hasActiveNote, - hasModifiedFiles, - hasConflicts, - hasRestorableDeletedNote, - hasNoRemote, - noteListSearchEnabled, - editorFindEnabled, - }) + useNativeMenuStateSync(menuState) }