diff --git a/.changeset/quiet-oranges-provide.md b/.changeset/quiet-oranges-provide.md new file mode 100644 index 000000000..910883961 --- /dev/null +++ b/.changeset/quiet-oranges-provide.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Fix dynamic tabs infinite loop diff --git a/packages/gitbook/src/components/DocumentView/Tabs/DynamicTabs.tsx b/packages/gitbook/src/components/DocumentView/Tabs/DynamicTabs.tsx index d0ec26549..506a78f1a 100644 --- a/packages/gitbook/src/components/DocumentView/Tabs/DynamicTabs.tsx +++ b/packages/gitbook/src/components/DocumentView/Tabs/DynamicTabs.tsx @@ -20,6 +20,7 @@ let globalTabsState: TabsState = (() => { const stored = localStorage.getItem('@gitbook/tabsState'); return stored ? (JSON.parse(stored) as TabsState) : { activeIds: {}, activeTitles: [] }; })(); + const listeners = new Set<() => void>(); function useTabsState() { @@ -30,13 +31,13 @@ function useTabsState() { const getSnapshot = useCallback(() => globalTabsState, []); - const setTabsState = (updater: (previous: TabsState) => TabsState) => { + const setTabsState = useCallback((updater: (previous: TabsState) => TabsState) => { globalTabsState = updater(globalTabsState); if (typeof localStorage !== 'undefined') { localStorage.setItem('@gitbook/tabsState', JSON.stringify(globalTabsState)); } listeners.forEach((listener) => listener()); - }; + }, []); const state = React.useSyncExternalStore(subscribe, getSnapshot, getSnapshot); return [state, setTabsState] as const; }