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();
|
keysAutoHide.toggle();
|
||||||
}, [headerAutoHide, keysAutoHide]);
|
}, [headerAutoHide, keysAutoHide]);
|
||||||
|
|
||||||
|
const handleTerminalReady = useCallback(
|
||||||
|
(sendData: (data: string) => void, connectionStatus: "connecting" | "connected" | "disconnected" | "error") => {
|
||||||
|
setTerminalRef({ sendData, connectionStatus });
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const handleSendKey = useCallback(
|
const handleSendKey = useCallback(
|
||||||
(data: string) => {
|
(data: string) => {
|
||||||
terminalRef?.sendData(data);
|
terminalRef?.sendData(data);
|
||||||
@@ -78,9 +85,7 @@ export const MobileTerminalWrapper: React.FC<MobileTerminalWrapperProps> = ({
|
|||||||
instanceId={instanceId}
|
instanceId={instanceId}
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
isMobile={true}
|
isMobile={true}
|
||||||
onTerminalReady={(sendData, connectionStatus) =>
|
onTerminalReady={handleTerminalReady}
|
||||||
setTerminalRef({ sendData, connectionStatus })
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
|
|||||||
const termRef = useRef<Terminal | null>(null);
|
const termRef = useRef<Terminal | null>(null);
|
||||||
const fitAddonRef = useRef<FitAddon | null>(null);
|
const fitAddonRef = useRef<FitAddon | null>(null);
|
||||||
const reconnectAttemptsRef = useRef(0);
|
const reconnectAttemptsRef = useRef(0);
|
||||||
|
const onTerminalReadyRef = useRef(onTerminalReady);
|
||||||
|
onTerminalReadyRef.current = onTerminalReady;
|
||||||
const [status, setStatus] = useState<
|
const [status, setStatus] = useState<
|
||||||
"connecting" | "connected" | "disconnected" | "error"
|
"connecting" | "connected" | "disconnected" | "error"
|
||||||
>("connecting");
|
>("connecting");
|
||||||
@@ -188,13 +190,13 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
|
|||||||
setTimeout(handleResize, 100);
|
setTimeout(handleResize, 100);
|
||||||
|
|
||||||
// Notify parent about terminal readiness
|
// Notify parent about terminal readiness
|
||||||
if (onTerminalReady) {
|
if (onTerminalReadyRef.current) {
|
||||||
const sendData = (data: string) => {
|
const sendData = (data: string) => {
|
||||||
if (ws.readyState === WebSocket.OPEN) {
|
if (ws.readyState === WebSocket.OPEN) {
|
||||||
ws.send(data);
|
ws.send(data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
onTerminalReady(sendData, status);
|
onTerminalReadyRef.current(sendData, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visibility API for reconnection
|
// Visibility API for reconnection
|
||||||
@@ -213,7 +215,7 @@ export const TerminalComponent: React.FC<TerminalProps> = ({
|
|||||||
ws.close();
|
ws.close();
|
||||||
term.dispose();
|
term.dispose();
|
||||||
};
|
};
|
||||||
}, [instanceId, connectWebSocket, onTerminalReady, status, calculateFontSize]);
|
}, [instanceId, connectWebSocket, calculateFontSize]);
|
||||||
|
|
||||||
// Update parent about status changes
|
// Update parent about status changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user