1- import React , { createRef , useEffect , useMemo } from 'react' ;
1+ import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
22import { ITerminalOptions , Terminal } from 'xterm' ;
33import * as TerminalFit from 'xterm/lib/addons/fit/fit' ;
44import SpinnerOverlay from '@/components/elements/SpinnerOverlay' ;
@@ -36,7 +36,8 @@ const terminalProps: ITerminalOptions = {
3636} ;
3737
3838export default ( ) => {
39- const ref = createRef < HTMLDivElement > ( ) ;
39+ const [ terminalElement , setTerminalElement ] = useState < HTMLDivElement | null > ( null ) ;
40+ const useRef = useCallback ( node => setTerminalElement ( node ) , [ ] ) ;
4041 const terminal = useMemo ( ( ) => new Terminal ( { ...terminalProps } ) , [ ] ) ;
4142 const { connected, instance } = ServerContext . useStoreState ( state => state . socket ) ;
4243
@@ -62,14 +63,14 @@ export default () => {
6263 } ;
6364
6465 useEffect ( ( ) => {
65- if ( ref . current && ! terminal . element ) {
66- terminal . open ( ref . current ) ;
66+ if ( connected && terminalElement && ! terminal . element ) {
67+ terminal . open ( terminalElement ) ;
6768
6869 // @see https://github.com/xtermjs/xterm.js/issues/2265
6970 // @see https://github.com/xtermjs/xterm.js/issues/2230
7071 TerminalFit . fit ( terminal ) ;
7172 }
72- } , [ terminal , ref ] ) ;
73+ } , [ terminal , connected , terminalElement ] ) ;
7374
7475 useEffect ( ( ) => {
7576 if ( connected && instance ) {
@@ -99,7 +100,7 @@ export default () => {
99100 maxHeight : '32rem' ,
100101 } }
101102 >
102- < div id = { 'terminal' } ref = { ref } />
103+ < div id = { 'terminal' } ref = { useRef } />
103104 </ div >
104105 < div className = { 'rounded-b bg-neutral-900 text-neutral-100 flex' } >
105106 < div className = { 'flex-no-shrink p-2 font-bold' } > $</ div >
0 commit comments