Files
Netcatty/application/state/activeTabStore.ts
T
LAPTOP-O016UC3M\Qi Chen c29fc418f9 Refactor state management for active tabs and optimize component rendering
- Introduced `activeTabStore` to manage active tab state with fine-grained subscriptions.
- Replaced direct prop passing of `isActive` with hooks (`useIsVaultActive`, `useIsSftpActive`) in components to determine active state.
- Memoized components (e.g., `SftpView`, `VaultView`, `TerminalLayer`, `TopTabs`) to prevent unnecessary re-renders.
- Updated various components to use `useCallback` and `useMemo` for stable references and performance improvements.
- Removed redundant state and props, simplifying the component structure.
- Disabled React.StrictMode in index.tsx for performance testing.
2025-12-08 20:08:52 +08:00

68 lines
2.0 KiB
TypeScript

import { useSyncExternalStore, useCallback, useRef } from 'react';
// Simple store for active tab that allows fine-grained subscriptions
type Listener = () => void;
class ActiveTabStore {
private activeTabId: string = 'vault';
private listeners = new Set<Listener>();
getActiveTabId = () => this.activeTabId;
setActiveTabId = (id: string) => {
if (this.activeTabId !== id) {
this.activeTabId = id;
this.listeners.forEach(listener => listener());
}
};
subscribe = (listener: Listener) => {
this.listeners.add(listener);
return () => this.listeners.delete(listener);
};
}
export const activeTabStore = new ActiveTabStore();
// Hook to read active tab ID - only re-renders when activeTabId changes
export const useActiveTabId = () => {
return useSyncExternalStore(
activeTabStore.subscribe,
activeTabStore.getActiveTabId
);
};
// Hook to get setter - never causes re-render
export const useSetActiveTabId = () => {
return activeTabStore.setActiveTabId;
};
// Check if a specific tab is active - only re-renders when this specific tab's active state changes
export const useIsTabActive = (tabId: string) => {
const getSnapshot = useCallback(() => activeTabStore.getActiveTabId() === tabId, [tabId]);
return useSyncExternalStore(activeTabStore.subscribe, getSnapshot);
};
// Check if vault is active
export const useIsVaultActive = () => {
return useSyncExternalStore(
activeTabStore.subscribe,
() => activeTabStore.getActiveTabId() === 'vault'
);
};
// Check if sftp is active
export const useIsSftpActive = () => {
return useSyncExternalStore(
activeTabStore.subscribe,
() => activeTabStore.getActiveTabId() === 'sftp'
);
};
// Check if terminal layer should be visible
export const useIsTerminalLayerVisible = (draggingSessionId: string | null) => {
const activeTabId = useActiveTabId();
const isTerminalTab = activeTabId !== 'vault' && activeTabId !== 'sftp';
return isTerminalTab || !!draggingSessionId;
};