Skip to content

Commit 80342e7

Browse files
authored
fix: prevent unnecessary re-renders by using ref for listeners (#12)
1 parent 5caea73 commit 80342e7

1 file changed

Lines changed: 24 additions & 46 deletions

File tree

src/xterm.tsx

Lines changed: 24 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { type ITerminalAddon, type ITerminalInitOnlyOptions, type ITerminalOptions, Terminal } from '@xterm/xterm'
22
import '@xterm/xterm/css/xterm.css'
3-
import { type ComponentPropsWithoutRef, useEffect, useRef, useState } from 'react'
3+
import { useEffect, useRef, useState, type ComponentPropsWithoutRef } from 'react'
44

55
export interface UseXTermProps {
66
addons?: ITerminalAddon[]
@@ -22,48 +22,42 @@ export interface UseXTermProps {
2222

2323
export function useXTerm({ options, addons, listeners }: UseXTermProps = {}) {
2424
const terminalRef = useRef<HTMLDivElement>(null)
25+
const listenersRef = useRef<UseXTermProps['listeners']>(listeners)
2526
const [terminalInstance, setTerminalInstance] = useState<Terminal | null>(null)
2627

28+
// Keep the latest version of listeners without retriggering the effect
29+
useEffect(() => {
30+
listenersRef.current = listeners
31+
}, [listeners])
32+
2733
useEffect(() => {
2834
const instance = new Terminal({
2935
fontFamily: 'operator mono,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace',
3036
fontSize: 14,
31-
theme: {
32-
background: '#101420',
33-
},
37+
theme: { background: '#101420' },
3438
cursorStyle: 'underline',
3539
cursorBlink: false,
3640
...options,
3741
})
3842

39-
// Load addons if the prop exists
40-
if (addons) {
41-
addons.forEach((addon) => {
42-
instance.loadAddon(addon)
43-
})
44-
}
45-
46-
// Listeners
47-
if (listeners) {
48-
if (listeners.onBinary) instance.onBinary(listeners.onBinary)
49-
if (listeners.onCursorMove) instance.onCursorMove(listeners.onCursorMove)
50-
if (listeners.onLineFeed) instance.onLineFeed(listeners.onLineFeed)
51-
if (listeners.onScroll) instance.onScroll(listeners.onScroll)
52-
if (listeners.onSelectionChange) instance.onSelectionChange(listeners.onSelectionChange)
53-
if (listeners.onRender) instance.onRender(listeners.onRender)
54-
if (listeners.onResize) instance.onResize(listeners.onResize)
55-
if (listeners.onTitleChange) instance.onTitleChange(listeners.onTitleChange)
56-
if (listeners.onKey) instance.onKey(listeners.onKey)
57-
if (listeners.onData) instance.onData(listeners.onData)
43+
// Load optional addons
44+
addons?.forEach((addon) => instance.loadAddon(addon))
5845

59-
// Add Custom Key Event Handler
60-
if (listeners.customKeyEventHandler) {
61-
instance.attachCustomKeyEventHandler(listeners.customKeyEventHandler)
62-
}
63-
}
46+
// Register event listeners from the ref
47+
const l = listenersRef.current
48+
l?.onBinary && instance.onBinary(l.onBinary)
49+
l?.onCursorMove && instance.onCursorMove(l.onCursorMove)
50+
l?.onLineFeed && instance.onLineFeed(l.onLineFeed)
51+
l?.onScroll && instance.onScroll(l.onScroll)
52+
l?.onSelectionChange && instance.onSelectionChange(l.onSelectionChange)
53+
l?.onRender && instance.onRender(l.onRender)
54+
l?.onResize && instance.onResize(l.onResize)
55+
l?.onTitleChange && instance.onTitleChange(l.onTitleChange)
56+
l?.onKey && instance.onKey(l.onKey)
57+
l?.onData && instance.onData(l.onData)
58+
l?.customKeyEventHandler && instance.attachCustomKeyEventHandler(l.customKeyEventHandler)
6459

6560
if (terminalRef.current) {
66-
// Mount terminal
6761
instance.open(terminalRef.current)
6862
instance.focus()
6963
}
@@ -74,23 +68,7 @@ export function useXTerm({ options, addons, listeners }: UseXTermProps = {}) {
7468
instance.dispose()
7569
setTerminalInstance(null)
7670
}
77-
}, [
78-
terminalRef,
79-
options,
80-
addons,
81-
listeners,
82-
listeners?.onBinary,
83-
listeners?.onCursorMove,
84-
listeners?.onData,
85-
listeners?.onKey,
86-
listeners?.onLineFeed,
87-
listeners?.onScroll,
88-
listeners?.onSelectionChange,
89-
listeners?.onRender,
90-
listeners?.onResize,
91-
listeners?.onTitleChange,
92-
listeners?.customKeyEventHandler,
93-
])
71+
}, [options, addons])
9472

9573
return {
9674
ref: terminalRef,

0 commit comments

Comments
 (0)