fix(git): restore changes panel visibility and sidebar sync (#886)
* fix: restore git changes panel visibility and sidebar sync
Two independent fixes:
1. ChangesSection virtualizer returned empty rows due to useMemo caching
getVirtualItems() with a stale stable reference. First render produced
an empty array, and useMemo never recomputed because rowVirtualizer
reference never changed. Removed the useMemo to call getVirtualItems()
directly on every render. Also added a ResizeObserver to force
remeasurement on visibility transitions (defensive).
2. RightSidebarTabs now keeps git status fresh while the sidebar is open
via useRightSidebarGitSync hook (10s polling with ensureStatus).
Replaces the GitPollingProvider removed in commit d9821716.
* fix(virtualizer): prevent React error #185 from render-phase getVirtualItems
Restoring useMemo for virtualRows with totalSize as an invalidation
dependency. Calling getVirtualItems() directly during render triggers
the virtualizer's maybeNotify() → onChange() → useReducer dispatch,
causing React error #185 (https://react.dev/errors/185 — cannot
update a component while rendering a different component).
The original useMemo([rowVirtualizer, shouldVirtualize]) was removed
because rowVirtualizer is a stable useState ref that never changes,
leaving the memo permanently stale after the first empty render.
Adding totalSize (from getTotalSize()) as a dependency solves this:
it changes whenever the virtualizer recalculates after measure/scroll,
ensuring getVirtualItems() returns fresh rows while staying wrapped
in useMemo.
This commit is contained in:
@@ -4,13 +4,44 @@ import { RiFolder3Line, RiGitBranchLine } from '@remixicon/react';
|
||||
import { SortableTabsStrip } from '@/components/ui/sortable-tabs-strip';
|
||||
import { GitView } from '@/components/views';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useGitStore } from '@/stores/useGitStore';
|
||||
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
|
||||
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
|
||||
import { SidebarFilesTree } from './SidebarFilesTree';
|
||||
|
||||
type RightTab = 'git' | 'files';
|
||||
|
||||
/**
|
||||
* Keeps git status fresh while the right sidebar is open.
|
||||
* Replaces the GitPollingProvider removed in commit b2d5ccb4.
|
||||
* The previous polling ran globally; now we only refresh when the sidebar is open.
|
||||
*/
|
||||
function useRightSidebarGitSync(directory: string | undefined, isSidebarOpen: boolean) {
|
||||
const { git } = useRuntimeAPIs();
|
||||
const ensureStatus = useGitStore((state) => state.ensureStatus);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!directory || !git || !isSidebarOpen) return;
|
||||
|
||||
void ensureStatus(directory, git);
|
||||
|
||||
const POLL_INTERVAL = 10_000;
|
||||
const id = setInterval(() => {
|
||||
if (typeof document !== 'undefined' && document.hidden) return;
|
||||
void ensureStatus(directory, git);
|
||||
}, POLL_INTERVAL);
|
||||
|
||||
return () => clearInterval(id);
|
||||
}, [directory, git, isSidebarOpen, ensureStatus]);
|
||||
}
|
||||
|
||||
export const RightSidebarTabs: React.FC = () => {
|
||||
const rightSidebarTab = useUIStore((state) => state.rightSidebarTab);
|
||||
const setRightSidebarTab = useUIStore((state) => state.setRightSidebarTab);
|
||||
const isRightSidebarOpen = useUIStore((state) => state.isRightSidebarOpen);
|
||||
const directory = useEffectiveDirectory();
|
||||
|
||||
useRightSidebarGitSync(directory, isRightSidebarOpen);
|
||||
|
||||
const tabItems = React.useMemo(() => [
|
||||
{
|
||||
@@ -44,4 +75,4 @@ export const RightSidebarTabs: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user