Refactor HostDeviceScanner for Enhanced Scanning Logic and State Management

- Introduced refs to manage scanning state and active host ID, improving control over scan initiation and termination.
- Updated useEffect to handle scanning conditions more effectively, including debouncing stop scan actions.
- Enhanced session management and error handling during network scans, ensuring better user feedback and reliability.
- Cleaned up component lifecycle management to prevent memory leaks and ensure proper resource cleanup.
This commit is contained in:
Tom Butcher 2026-09-14 23:11:21 +01:00
parent e32e48fa3a
commit 8adf2d7847

View File

@ -52,6 +52,9 @@ const HostDeviceScanner = ({
? crypto.randomUUID()
: `scan-${Date.now()}-${Math.random().toString(16).slice(2)}`
)
const startedRef = useRef(false)
const activeHostIdRef = useRef(null)
const pendingStopRef = useRef(null)
const [scanning, setScanning] = useState(false)
const [progress, setProgress] = useState(0)
@ -80,22 +83,52 @@ const HostDeviceScanner = ({
}
useEffect(() => {
if (!hostId || connected !== true || !compatible) {
const sessionId = sessionIdRef.current
const canScan = Boolean(hostId) && connected === true && compatible
const stopScan = (targetHostId) => {
if (!targetHostId || !startedRef.current) {
return
}
sendObjectActionRef.current(targetHostId, 'host', {
type: 'scanNetworkStop',
data: { sessionId }
})
startedRef.current = false
activeHostIdRef.current = null
}
if (pendingStopRef.current) {
clearTimeout(pendingStopRef.current)
pendingStopRef.current = null
}
if (!canScan) {
const hostToStop = activeHostIdRef.current
pendingStopRef.current = setTimeout(() => {
stopScan(hostToStop)
pendingStopRef.current = null
}, 250)
return () => {
if (pendingStopRef.current) {
clearTimeout(pendingStopRef.current)
pendingStopRef.current = null
}
}
}
let cancelled = false
const sessionId = sessionIdRef.current
console.log('Scan session id:', sessionId)
const isSessionEvent = (event) => event?.data?.sessionId === sessionId
const startScan = () => {
if (cancelled) return
setProgress(0)
setCurrentIP(null)
setScanError(null)
setScanning(true)
setDevices([])
setSelectedKey(null)
sendObjectActionRef.current(
hostId,
@ -113,6 +146,7 @@ const HostDeviceScanner = ({
if (result?.success === false) {
setScanning(false)
setScanError(result.error || 'Failed to start network scan')
startedRef.current = false
}
}
)
@ -192,29 +226,27 @@ const HostDeviceScanner = ({
onComplete
)
setDevices([])
setSelectedKey(null)
const alreadyRunning = startedRef.current && activeHostIdRef.current === hostId
if (!alreadyRunning) {
if (startedRef.current && activeHostIdRef.current) {
stopScan(activeHostIdRef.current)
}
startedRef.current = true
activeHostIdRef.current = hostId
startScan()
}
return () => {
cancelled = true
if (unsubFound) unsubFound()
if (unsubProgress) unsubProgress()
if (unsubComplete) unsubComplete()
sendObjectActionRef.current(hostId, 'host', {
type: 'scanNetworkStop',
data: { sessionId }
})
pendingStopRef.current = setTimeout(() => {
stopScan(hostId)
pendingStopRef.current = null
}, 250)
}
}, [
hostId,
connected,
compatible,
port,
protocol,
connectionInterface,
objectType
])
}, [hostId, connected, compatible])
const applyDevice = useCallback(
(device) => {