From 6306ea5efe6726fd27a969e8aba37671a2dad638 Mon Sep 17 00:00:00 2001 From: Katerina Koukiou Date: Thu, 8 Dec 2022 14:37:08 +0100 Subject: [PATCH] fix(VncConsole): prevent running initialization code more than once (#8373) (#8374) The functions that were on the dependency list of the useEffect hook got redefined each time the component got updated, resulting in the component's initialization code, from within the useEffect hook, to be running more than once. That was unwanted behavior and the useCallback wrappers should prevent it. --- .../src/components/VncConsole/VncConsole.tsx | 82 +++++++++++-------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/packages/react-console/src/components/VncConsole/VncConsole.tsx b/packages/react-console/src/components/VncConsole/VncConsole.tsx index c8ac73999e2..89355de0686 100644 --- a/packages/react-console/src/components/VncConsole/VncConsole.tsx +++ b/packages/react-console/src/components/VncConsole/VncConsole.tsx @@ -92,28 +92,53 @@ export const VncConsole: React.FunctionComponent = ({ textCtrlAltDel }) => { const rfb = React.useRef(); - let novncStaticComponent: React.ReactNode; - let novncElem: HTMLDivElement; + const novncElem = React.useRef(null); const [status, setStatus] = React.useState(CONNECTING); - const addEventListeners = () => { + const onConnected = () => { + setStatus(CONNECTED); + }; + + const _onDisconnected = React.useCallback( + (e: any) => { + setStatus(DISCONNECTED); + onDisconnected(e); + }, + [onDisconnected] + ); + + const _onSecurityFailure = React.useCallback( + (e: any) => { + setStatus(DISCONNECTED); + onSecurityFailure(e); + }, + [onSecurityFailure] + ); + + const onCtrlAltDel = () => { + if (rfb.current) { + rfb?.current?.sendCtrlAltDel(); + } + }; + + const addEventListeners = React.useCallback(() => { if (rfb.current) { rfb.current?.addEventListener('connect', onConnected); rfb.current?.addEventListener('disconnect', _onDisconnected); rfb.current?.addEventListener('securityfailure', _onSecurityFailure); } - }; + }, [rfb, _onDisconnected, _onSecurityFailure]); - const removeEventListeners = () => { + const removeEventListeners = React.useCallback(() => { if (rfb.current) { rfb.current.removeEventListener('connect', onConnected); rfb.current.removeEventListener('disconnect', _onDisconnected); rfb.current.removeEventListener('securityfailure', _onSecurityFailure); } - }; + }, [rfb, _onDisconnected, _onSecurityFailure]); - const connect = () => { + const connect = React.useCallback(() => { const protocol = encrypt ? 'wss' : 'ws'; const url = `${protocol}://${host}:${port}/${path}`; @@ -122,12 +147,25 @@ export const VncConsole: React.FunctionComponent = ({ shared, credentials }; - rfb.current = new RFB(novncElem, url, options); + rfb.current = new RFB(novncElem.current, url, options); addEventListeners(); rfb.current.viewOnly = viewOnly; rfb.current.scaleViewport = scaleViewport; rfb.current.resizeSession = resizeSession; - }; + }, [ + addEventListeners, + host, + path, + port, + resizeSession, + scaleViewport, + viewOnly, + encrypt, + rfb, + repeaterID, + shared, + credentials + ]); React.useEffect(() => { initLogging(vncLogging); @@ -152,26 +190,6 @@ export const VncConsole: React.FunctionComponent = ({ rfb.current.disconnect(); }; - const onConnected = () => { - setStatus(CONNECTED); - }; - - const _onDisconnected = (e: any) => { - setStatus(DISCONNECTED); - onDisconnected(e); - }; - - const _onSecurityFailure = (e: any) => { - setStatus(DISCONNECTED); - onSecurityFailure(e); - }; - - const onCtrlAltDel = () => { - if (rfb.current) { - rfb?.current?.sendCtrlAltDel(); - } - }; - let rightContent; let emptyState; switch (status) { @@ -207,10 +225,6 @@ export const VncConsole: React.FunctionComponent = ({ ); } - if (!novncStaticComponent) { - novncStaticComponent =
(novncElem = e)} />; - } - return ( <> {rightContent} @@ -219,7 +233,7 @@ export const VncConsole: React.FunctionComponent = ({
{emptyState} - {novncStaticComponent} +