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:
@@ -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>
|
||||
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user