diff --git a/static/app/views/discover/results/resultsChart.tsx b/static/app/views/discover/results/resultsChart.tsx index f4ae29e6b7e8..f454ba377538 100644 --- a/static/app/views/discover/results/resultsChart.tsx +++ b/static/app/views/discover/results/resultsChart.tsx @@ -1,10 +1,8 @@ -import {Component, Fragment} from 'react'; +import {Fragment, memo, useContext, useMemo} from 'react'; import styled from '@emotion/styled'; import type {Location} from 'history'; import isEqual from 'lodash/isEqual'; -import type {SelectValue} from '@sentry/scraps/select'; - import type {Client} from 'sentry/api'; import {AreaChart} from 'sentry/components/charts/areaChart'; import {BarChart} from 'sentry/components/charts/barChart'; @@ -27,9 +25,8 @@ import { TOP_N, } from 'sentry/utils/discover/types'; import {getDynamicText} from 'sentry/utils/getDynamicText'; -import {valueIsEqual} from 'sentry/utils/object/valueIsEqual'; import {decodeScalar} from 'sentry/utils/queryString'; -import {withApi} from 'sentry/utils/withApi'; +import {useApi} from 'sentry/utils/useApi'; import {isCustomMeasurement} from 'sentry/views/dashboards/utils'; import {ChartFooter} from 'sentry/views/discover/results/chartFooter'; @@ -43,29 +40,16 @@ type ResultsChartProps = { customMeasurements?: CustomMeasurementCollection | undefined; }; -class ResultsChart extends Component { - shouldComponentUpdate(nextProps: ResultsChartProps) { - const {eventView, ...restProps} = this.props; - const {eventView: nextEventView, ...restNextProps} = nextProps; - - if (!eventView.isEqualTo(nextEventView)) { - return true; - } - - return !isEqual(restProps, restNextProps); - } - - render() { - const { - api, - eventView, - location, - organization, - confirmedQuery, - yAxisValue, - customMeasurements, - } = this.props; - +const ResultsChart = memo( + function ResultsChart({ + api, + eventView, + location, + organization, + confirmedQuery, + yAxisValue, + customMeasurements, + }: ResultsChartProps) { const globalSelection = eventView.getPageFilters(); const start = globalSelection.datetime.start ? getUtcToLocalDateObject(globalSelection.datetime.start) @@ -154,11 +138,18 @@ class ResultsChart extends Component { })} ); + }, + function areEqual(prev: ResultsChartProps, next: ResultsChartProps) { + const {eventView, ...restPrev} = prev; + const {eventView: nextEventView, ...restNext} = next; + if (!eventView.isEqualTo(nextEventView)) { + return false; + } + return isEqual(restPrev, restNext); } -} +); type ContainerProps = { - api: Client; confirmedQuery: boolean; eventView: EventView; location: Location; @@ -173,54 +164,27 @@ type ContainerProps = { yAxis: string[]; }; -type ContainerState = { - yAxisOptions: Array>; -}; - -class ResultsChartContainer extends Component { - state: ContainerState = { - yAxisOptions: this.props.eventView.getYAxisOptions(), - }; - - UNSAFE_componentWillReceiveProps(nextProps: any) { - const yAxisOptions = this.props.eventView.getYAxisOptions(); - const nextYAxisOptions = nextProps.eventView.getYAxisOptions(); - - if (!valueIsEqual(yAxisOptions, nextYAxisOptions, true)) { - this.setState({yAxisOptions: nextYAxisOptions}); - } - } - - shouldComponentUpdate(nextProps: ContainerProps) { - const {eventView, ...restProps} = this.props; - const {eventView: nextEventView, ...restNextProps} = nextProps; - - if ( - !eventView.isEqualTo(nextEventView) || - this.props.confirmedQuery !== nextProps.confirmedQuery - ) { - return true; - } - - return !isEqual(restProps, restNextProps); - } - - render() { - const { - api, - eventView, - location, - total, - onAxisChange, - onDisplayChange, - onIntervalChange, - onTopEventsChange, - organization, - confirmedQuery, - yAxis, - } = this.props; +export const ResultsChartContainer = memo( + function ResultsChartContainer({ + eventView, + location, + total, + onAxisChange, + onDisplayChange, + onIntervalChange, + onTopEventsChange, + organization, + confirmedQuery, + yAxis, + }: ContainerProps) { + const api = useApi(); + const customMeasurementsContext = useContext(CustomMeasurementsContext); - const {yAxisOptions} = this.state; + const yAxisOptions = useMemo( + () => eventView.getYAxisOptions(), + // eslint-disable-next-line react-hooks/exhaustive-deps + [eventView] + ); const hasQueryFeature = organization.features.includes('discover-query'); const displayOptions = eventView @@ -257,19 +221,15 @@ class ResultsChartContainer extends Component { return ( {(yAxis.length > 0 && ( - - {contextValue => ( - - )} - + )) || {t('No Y-Axis selected.')}} { /> ); + }, + function areContainerEqual(prev: ContainerProps, next: ContainerProps) { + const {eventView, ...restPrev} = prev; + const {eventView: nextEventView, ...restNext} = next; + if ( + !eventView.isEqualTo(nextEventView) || + prev.confirmedQuery !== next.confirmedQuery + ) { + return false; + } + return isEqual(restPrev, restNext); } -} - -export default withApi(ResultsChartContainer); +); const StyledPanel = styled(Panel)` @container (min-width: ${p => p.theme.container['4xl']}) {