diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index 15b674cb0b8..7b890272d80 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -18,7 +18,7 @@ */ import 'src/public-path'; -import { lazy, StrictMode, Suspense } from 'react'; +import { lazy, StrictMode, Suspense, useEffect } from 'react'; import { createRoot, type Root } from 'react-dom/client'; import { BrowserRouter as Router, Route } from 'react-router-dom'; import { Global } from '@emotion/react'; @@ -68,18 +68,19 @@ const LazyDashboardPage = lazy( const EmbededLazyDashboardPage = () => { const uiConfig = useUiConfig(); + const emitDataMasks = uiConfig?.emitDataMasks; - // Emit data mask changes to the parent window - if (uiConfig?.emitDataMasks) { + // Emit data mask changes to the parent window. Subscribing inside an effect + // (rather than during render) ensures the unsubscribe runs on unmount, + // including StrictMode's dev-mode double-mount cycle. + useEffect(() => { + if (!emitDataMasks) return undefined; log('setting up Switchboard event emitter'); let previousDataMask = store.getState().dataMask; - store.subscribe(() => { - const currentState = store.getState(); - const currentDataMask = currentState.dataMask; - - // Only emit if the dataMask has changed + return store.subscribe(() => { + const currentDataMask = store.getState().dataMask; if (previousDataMask !== currentDataMask) { Switchboard.emit('observeDataMask', { ...currentDataMask, @@ -88,7 +89,7 @@ const EmbededLazyDashboardPage = () => { previousDataMask = currentDataMask; } }); - } + }, [emitDataMasks]); return ; };