diff --git a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx index eb63d8f08..0bcef96bc 100644 --- a/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx +++ b/frontend/app/components/Dashboard/components/WidgetChart/WidgetChart.tsx @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect } from 'react'; +import React, { useState, useRef, useEffect, useCallback } from 'react'; import CustomMetriLineChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetriLineChart'; import CustomMetricPercentage from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricPercentage'; import CustomMetricTable from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricTable'; @@ -9,8 +9,10 @@ import { Loader } from 'UI'; import { useStore } from 'App/mstore'; import WidgetPredefinedChart from '../WidgetPredefinedChart'; import CustomMetricOverviewChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricOverviewChart'; -import { getStartAndEndTimestampsByDensity } from 'Types/dashboard/helper'; +import { getStartAndEndTimestampsByDensity } from 'Types/dashboard/helper'; import { debounce } from 'App/utils'; +import useIsMounted from 'App/hooks/useIsMounted' + interface Props { metric: any; isWidget?: boolean @@ -24,12 +26,12 @@ function WidgetChart(props: Props) { const colors = Styles.customMetricColors; const [loading, setLoading] = useState(true) const isOverviewWidget = metric.metricType === 'predefined' && metric.viewType === 'overview'; - const params = { density: isOverviewWidget ? 7 : 70 } + const params = { density: isOverviewWidget ? 7 : 70 } const metricParams = { ...params } const prevMetricRef = useRef(); + const isMounted = useIsMounted(); const [data, setData] = useState(metric.data); - const isTableWidget = metric.metricType === 'table' && metric.viewType === 'table'; const isPieChart = metric.metricType === 'table' && metric.viewType === 'pieChart'; @@ -57,16 +59,16 @@ function WidgetChart(props: Props) { const depsString = JSON.stringify(_metric.series); - const fetchMetricChartData = (metric, payload, isWidget) => { + if (!isMounted()) return; setLoading(true) dashboardStore.fetchMetricChartData(metric, payload, isWidget).then((res: any) => { - setData(res); + if (isMounted()) setData(res); }).finally(() => { setLoading(false); }); } - + const debounceRequest: any = React.useCallback(debounce(fetchMetricChartData, 500), []); useEffect(() => { if (prevMetricRef.current && prevMetricRef.current.name !== metric.name) { @@ -137,4 +139,4 @@ function WidgetChart(props: Props) { )); } -export default observer(WidgetChart); \ No newline at end of file +export default observer(WidgetChart); diff --git a/frontend/app/components/Dashboard/components/WidgetSessions/WidgetSessions.tsx b/frontend/app/components/Dashboard/components/WidgetSessions/WidgetSessions.tsx index 9f2f1cb3d..7e199b3d5 100644 --- a/frontend/app/components/Dashboard/components/WidgetSessions/WidgetSessions.tsx +++ b/frontend/app/components/Dashboard/components/WidgetSessions/WidgetSessions.tsx @@ -6,13 +6,15 @@ import SessionItem from 'Shared/SessionItem'; import { observer, useObserver } from 'mobx-react-lite'; import { DateTime } from 'luxon'; import { debounce } from 'App/utils'; +import useIsMounted from 'App/hooks/useIsMounted' + interface Props { className?: string; } function WidgetSessions(props: Props) { const { className = '' } = props; const [data, setData] = useState([]); - + const isMounted = useIsMounted() const [loading, setLoading] = useState(false); const [seriesOptions, setSeriesOptions] = useState([ { text: 'All', value: 'all' }, @@ -34,6 +36,7 @@ function WidgetSessions(props: Props) { }, [data]); const fetchSessions = (metricId, filter) => { + if (!isMounted()) return; setLoading(true) widget.fetchSessions(metricId, filter).then(res => { setData(res) @@ -41,7 +44,7 @@ function WidgetSessions(props: Props) { setLoading(false) }); } - + const filteredSessions = getListSessionsBySeries(data, activeSeries); const { dashboardStore, metricStore } = useStore(); const filter = useObserver(() => dashboardStore.drillDownFilter); @@ -126,4 +129,4 @@ const getListSessionsBySeries = (data, seriesId) => { return arr; } -export default observer(WidgetSessions); \ No newline at end of file +export default observer(WidgetSessions); diff --git a/frontend/app/hooks/useIsMounted.ts b/frontend/app/hooks/useIsMounted.ts new file mode 100644 index 000000000..3587a3351 --- /dev/null +++ b/frontend/app/hooks/useIsMounted.ts @@ -0,0 +1,14 @@ +import { useRef, useEffect, useCallback } from 'react' + +export default function useIsMounted(): () => boolean { + const ref = useRef(false); + + useEffect(() => { + ref.current = true; + return () => { + ref.current = false; + }; + }, []); + + return useCallback(() => ref.current, [ref]); +}