fix(renderer): stabilize onResize ref to prevent rrp constraint race (#193)

Wrap handleInspectorResize in useCallback so rrp v4's panel registration
useLayoutEffect (which includes onResize in its dep array) does not
de-register/re-register the inspector panel on every render.

Without this, any re-render of SessionView (workspace data arriving,
daemon status change, etc.) created a new handleInspectorResize reference,
triggering rrp's cleanup → re-registration cycle. With React 19's automatic
batching, this window reliably overlapped with the expand()/collapse()
useEffect on initial sidebar click, causing the "Panel constraints not found
for Panel inspector" throw that tore down the session view.

Closes #185.
This commit is contained in:
Harshit Singh Bhandari 2026-06-12 18:24:02 +05:30 committed by GitHub
parent 295cda5787
commit dac53d8295
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 18 additions and 11 deletions

View File

@ -1,4 +1,4 @@
import { useEffect, useRef } from "react";
import { useCallback, useEffect, useRef } from "react";
import type { PanelImperativeHandle, PanelSize } from "react-resizable-panels";
import { CenterPane } from "./CenterPane";
import { SessionInspector } from "./SessionInspector";
@ -116,16 +116,23 @@ export function SessionView({ sessionId }: SessionViewProps) {
// data-separator="active" only during a pointer drag — the same hook the
// transition-suppressing CSS keys on, so drag writes are never transition
// frames.
const handleInspectorResize = (size: PanelSize) => {
if (inspectorSeparatorRef.current?.getAttribute("data-separator") !== "active") return;
const open = useUiStore.getState().isInspectorOpen;
if (size.asPercentage > 0) {
window.localStorage?.setItem(inspectorSplitStorageKey, String(size.asPercentage));
if (!open) toggleInspector();
} else if (open) {
toggleInspector();
}
};
// Also wrapped in useCallback: rrp v4's panel registration useLayoutEffect
// includes onResize in its dep array, so an unstable reference would
// de-register/re-register the inspector panel on every render and race
// with the expand()/collapse() effect above.
const handleInspectorResize = useCallback(
(size: PanelSize) => {
if (inspectorSeparatorRef.current?.getAttribute("data-separator") !== "active") return;
const open = useUiStore.getState().isInspectorOpen;
if (size.asPercentage > 0) {
window.localStorage?.setItem(inspectorSplitStorageKey, String(size.asPercentage));
if (!open) toggleInspector();
} else if (open) {
toggleInspector();
}
},
[toggleInspector],
);
if (!session && !workspaceQuery.isLoading) {
return (