fix: prevent infinite terminal re-initialization loop

- Remove status from TerminalComponent useEffect dependencies to prevent recreation on WebSocket status changes
- Use ref for onTerminalReady callback to avoid parent re-renders triggering terminal recreation
- Wrap MobileTerminalWrapper onTerminalReady with useCallback for stable reference
This commit is contained in:
Fusion
2026-05-24 11:35:32 +02:00
parent b6bda3d692
commit aea1ff95f6
2 changed files with 13 additions and 6 deletions
@@ -39,6 +39,13 @@ export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
keysAutoHide.toggle();
}, [headerAutoHide, keysAutoHide]);
const handleTerminalReady = useCallback(
(sendData: (data: string) => void, connectionStatus: "connecting" | "connected" | "disconnected" | "error") => {
setTerminalRef({ sendData, connectionStatus });
},
[]
);
const handleSendKey = useCallback(
(data: string) => {
terminalRef?.sendData(data);
@@ -78,9 +85,7 @@ export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
instanceId={instanceId}
onClose={onClose}
isMobile={true}
onTerminalReady={(sendData, connectionStatus) =>
setTerminalRef({ sendData, connectionStatus })
}
onTerminalReady={handleTerminalReady}
/>
</div>
+5 -3
View File
@@ -32,6 +32,8 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
const termRef = useRef<Terminal | null>(null);
const fitAddonRef = useRef<FitAddon | null>(null);
const reconnectAttemptsRef = useRef(0);
const onTerminalReadyRef = useRef(onTerminalReady);
onTerminalReadyRef.current = onTerminalReady;
const [status, setStatus] = useState<
"connecting" | "connected" | "disconnected" | "error"
>("connecting");
@@ -188,13 +190,13 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
setTimeout(handleResize, 100);
// Notify parent about terminal readiness
if (onTerminalReady) {
if (onTerminalReadyRef.current) {
const sendData = (data: string) => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(data);
}
};
onTerminalReady(sendData, status);
onTerminalReadyRef.current(sendData, status);
}
// Visibility API for reconnection
@@ -213,7 +215,7 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
ws.close();
term.dispose();
};
}, [instanceId, connectWebSocket, onTerminalReady, status, calculateFontSize]);
}, [instanceId, connectWebSocket, calculateFontSize]);
// Update parent about status changes
useEffect(() => {