mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
fix(embedded): move dataMask store.subscribe into an effect
Per codeant review on #39893: subscribing to the Redux store from inside the render body of EmbededLazyDashboardPage registered a new listener on every render with no cleanup, leaking subscriptions and double-emitting observeDataMask events on each store update. StrictMode's dev-mode double-mount made the leak immediately visible. Move the subscription into a useEffect keyed on emitDataMasks, returning the Redux unsubscribe so React tears the listener down on unmount. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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 <LazyDashboardPage idOrSlug={bootstrapData.embedded!.dashboard_id} />;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user