From faffcc6bfe3d34cf2e422dc99b7f97ef6dfce6d9 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Fri, 11 Sep 2020 13:18:23 +0200 Subject: [PATCH 1/2] Re-enable rule no-access-state-in-setstate --- superset-frontend/.eslintrc.js | 2 -- .../src/CRUD/CollectionTable.tsx | 8 +++---- .../src/SqlLab/components/LimitControl.tsx | 2 +- .../src/SqlLab/components/ResultSet.tsx | 6 ++--- .../src/SqlLab/components/SaveQuery.jsx | 2 +- .../SqlLab/components/ScheduleQueryButton.jsx | 2 +- .../src/SqlLab/components/SqlEditor.jsx | 4 +++- .../SqlLab/components/TabbedSqlEditors.jsx | 2 +- .../src/SqlLab/components/TableElement.jsx | 2 +- .../src/components/OmniContainer.jsx | 2 +- .../src/dashboard/components/SaveModal.jsx | 4 +++- .../src/dashboard/components/SliceAdder.jsx | 12 +++++----- .../components/SliceHeaderControls.jsx | 6 ++--- .../components/gridComponents/ChartHolder.jsx | 2 +- .../src/datasource/DatasourceEditor.jsx | 5 +++- .../components/AdhocMetricEditPopover.jsx | 24 +++++++++---------- .../components/ControlPanelSection.jsx | 2 +- .../components/ExploreViewContainer.jsx | 2 +- .../components/controls/AnnotationLayer.jsx | 2 +- .../components/controls/BoundsControl.jsx | 12 +++++----- .../components/controls/DateFilterControl.jsx | 12 +++++----- .../controls/FixedOrMetricControl.jsx | 7 +++--- .../components/controls/SpatialControl.jsx | 2 +- .../components/controls/VizTypeControl.jsx | 2 +- .../visualizations/FilterBox/FilterBox.jsx | 23 +++++++++++------- 25 files changed, 79 insertions(+), 70 deletions(-) diff --git a/superset-frontend/.eslintrc.js b/superset-frontend/.eslintrc.js index 37590b53f46c7..1d5c49220d77b 100644 --- a/superset-frontend/.eslintrc.js +++ b/superset-frontend/.eslintrc.js @@ -124,7 +124,6 @@ module.exports = { 'react/jsx-fragments': 1, 'react/jsx-no-bind': 0, 'react/jsx-props-no-spreading': 0, // re-enable up for discussion - 'react/no-access-state-in-setstate': 0, // disabled temporarily 'react/no-array-index-key': 0, 'react/no-string-refs': 0, 'react/no-unescaped-entities': 0, @@ -236,7 +235,6 @@ module.exports = { 'react/jsx-fragments': 1, 'react/jsx-no-bind': 0, 'react/jsx-props-no-spreading': 0, // re-enable up for discussion - 'react/no-access-state-in-setstate': 0, // disabled temporarily 'react/no-array-index-key': 0, 'react/no-string-refs': 0, 'react/no-unescaped-entities': 0, diff --git a/superset-frontend/src/CRUD/CollectionTable.tsx b/superset-frontend/src/CRUD/CollectionTable.tsx index f1620f43e9563..4e918665ba099 100644 --- a/superset-frontend/src/CRUD/CollectionTable.tsx +++ b/superset-frontend/src/CRUD/CollectionTable.tsx @@ -150,12 +150,12 @@ export default class CRUDCollection extends React.PureComponent< toggleExpand(id: any) { this.onCellChange(id, '__expanded', false); - this.setState({ + this.setState(prevState => ({ expandedColumns: { - ...this.state.expandedColumns, - [id]: !this.state.expandedColumns[id], + ...prevState.expandedColumns, + [id]: !prevState.expandedColumns[id], }, - }); + })); } renderHeaderRow() { diff --git a/superset-frontend/src/SqlLab/components/LimitControl.tsx b/superset-frontend/src/SqlLab/components/LimitControl.tsx index 2b924a7ae3ece..d0def628b3bf9 100644 --- a/superset-frontend/src/SqlLab/components/LimitControl.tsx +++ b/superset-frontend/src/SqlLab/components/LimitControl.tsx @@ -77,7 +77,7 @@ export default class LimitControl extends React.PureComponent< } handleToggle() { - this.setState({ showOverlay: !this.state.showOverlay }); + this.setState(prevState => ({ showOverlay: !prevState.showOverlay })); } handleHide() { diff --git a/superset-frontend/src/SqlLab/components/ResultSet.tsx b/superset-frontend/src/SqlLab/components/ResultSet.tsx index 1846ddc1ae950..14b38bb0ee891 100644 --- a/superset-frontend/src/SqlLab/components/ResultSet.tsx +++ b/superset-frontend/src/SqlLab/components/ResultSet.tsx @@ -129,9 +129,9 @@ export default class ResultSet extends React.PureComponent< } toggleExploreResultsButton() { - this.setState({ - showExploreResultsButton: !this.state.showExploreResultsButton, - }); + this.setState(prevState => ({ + showExploreResultsButton: !prevState.showExploreResultsButton, + })); } changeSearch(event: React.ChangeEvent) { diff --git a/superset-frontend/src/SqlLab/components/SaveQuery.jsx b/superset-frontend/src/SqlLab/components/SaveQuery.jsx index cbda842dc0db3..9dfb7fd20c9bc 100644 --- a/superset-frontend/src/SqlLab/components/SaveQuery.jsx +++ b/superset-frontend/src/SqlLab/components/SaveQuery.jsx @@ -91,7 +91,7 @@ class SaveQuery extends React.PureComponent { } toggleSave() { - this.setState({ showSave: !this.state.showSave }); + this.setState(prevState => ({ showSave: !prevState.showSave })); } renderModalBody() { diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx index f9a778dd5d59c..07312e7804b4d 100644 --- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx +++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton.jsx @@ -133,7 +133,7 @@ class ScheduleQueryButton extends React.PureComponent { } toggleSchedule() { - this.setState({ showSchedule: !this.state.showSchedule }); + this.setState(prevState => ({ showSchedule: !prevState.showSchedule })); } renderModalBody() { diff --git a/superset-frontend/src/SqlLab/components/SqlEditor.jsx b/superset-frontend/src/SqlLab/components/SqlEditor.jsx index 7a3455e22520e..aeaa9d0bd26dd 100644 --- a/superset-frontend/src/SqlLab/components/SqlEditor.jsx +++ b/superset-frontend/src/SqlLab/components/SqlEditor.jsx @@ -260,7 +260,9 @@ class SqlEditor extends React.PureComponent { } handleToggleAutocompleteEnabled = () => { - this.setState({ autocompleteEnabled: !this.state.autocompleteEnabled }); + this.setState(prevState => ({ + autocompleteEnabled: !prevState.autocompleteEnabled, + })); }; handleWindowResize() { diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors.jsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors.jsx index 2959427526234..4d1ff6410444a 100644 --- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors.jsx +++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors.jsx @@ -278,7 +278,7 @@ class TabbedSqlEditors extends React.PureComponent { } toggleLeftBar() { - this.setState({ hideLeftBar: !this.state.hideLeftBar }); + this.setState(prevState => ({ hideLeftBar: !prevState.hideLeftBar })); } render() { diff --git a/superset-frontend/src/SqlLab/components/TableElement.jsx b/superset-frontend/src/SqlLab/components/TableElement.jsx index f6bbabfc3c325..aeca231e7a08d 100644 --- a/superset-frontend/src/SqlLab/components/TableElement.jsx +++ b/superset-frontend/src/SqlLab/components/TableElement.jsx @@ -85,7 +85,7 @@ class TableElement extends React.PureComponent { } toggleSortColumns() { - this.setState({ sortColumns: !this.state.sortColumns }); + this.setState(prevState => ({ sortColumns: !prevState.sortColumns })); } removeFromStore() { diff --git a/superset-frontend/src/components/OmniContainer.jsx b/superset-frontend/src/components/OmniContainer.jsx index 3020d9a82a596..7249f3f105c29 100644 --- a/superset-frontend/src/components/OmniContainer.jsx +++ b/superset-frontend/src/components/OmniContainer.jsx @@ -70,7 +70,7 @@ class OmniContainer extends React.Component { show_omni: !this.state.showOmni, }); - this.setState({ showOmni: !this.state.showOmni }); + this.setState(prevState => ({ showOmni: !prevState.showOmni })); document.getElementsByClassName('Omnibar')[0].focus(); } diff --git a/superset-frontend/src/dashboard/components/SaveModal.jsx b/superset-frontend/src/dashboard/components/SaveModal.jsx index eb2b0bd9b8676..3e69d538317e8 100644 --- a/superset-frontend/src/dashboard/components/SaveModal.jsx +++ b/superset-frontend/src/dashboard/components/SaveModal.jsx @@ -75,7 +75,9 @@ class SaveModal extends React.PureComponent { } toggleDuplicateSlices() { - this.setState({ duplicateSlices: !this.state.duplicateSlices }); + this.setState(prevState => ({ + duplicateSlices: !prevState.duplicateSlices, + })); } handleSaveTypeChange(event) { diff --git a/superset-frontend/src/dashboard/components/SliceAdder.jsx b/superset-frontend/src/dashboard/components/SliceAdder.jsx index 5bfc1441602c1..9034a8105a380 100644 --- a/superset-frontend/src/dashboard/components/SliceAdder.jsx +++ b/superset-frontend/src/dashboard/components/SliceAdder.jsx @@ -135,23 +135,23 @@ class SliceAdder extends React.Component { } searchUpdated(searchTerm) { - this.setState({ + this.setState(prevState => ({ searchTerm, filteredSlices: this.getFilteredSortedSlices( searchTerm, - this.state.sortBy, + prevState.sortBy, ), - }); + })); } handleSelect(sortBy) { - this.setState({ + this.setState(prevState => ({ sortBy, filteredSlices: this.getFilteredSortedSlices( - this.state.searchTerm, + prevState.searchTerm, sortBy, ), - }); + })); } rowRenderer({ key, index, style }) { diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx index 0e6b188685ca5..728954099a930 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls.jsx @@ -103,9 +103,9 @@ class SliceHeaderControls extends React.PureComponent { } toggleControls() { - this.setState({ - showControls: !this.state.showControls, - }); + this.setState(prevState => ({ + showControls: !prevState.showControls, + })); } handleToggleFullSize() { diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx index 09a1ae54ac636..10a61cf0ca93d 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx +++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx @@ -163,7 +163,7 @@ class ChartHolder extends React.Component { } handleToggleFullSize() { - this.setState(() => ({ isFullSize: !this.state.isFullSize })); + this.setState(prevState => ({ isFullSize: !prevState.isFullSize })); } render() { diff --git a/superset-frontend/src/datasource/DatasourceEditor.jsx b/superset-frontend/src/datasource/DatasourceEditor.jsx index 1d3d4f141289e..93db71ce6576b 100644 --- a/superset-frontend/src/datasource/DatasourceEditor.jsx +++ b/superset-frontend/src/datasource/DatasourceEditor.jsx @@ -289,7 +289,10 @@ class DatasourceEditor extends React.PureComponent { onDatasourcePropChange(attr, value) { const datasource = { ...this.state.datasource, [attr]: value }; - this.setState({ datasource }, this.onDatasourceChange(datasource)); + this.setState( + prevState => ({ datasource: { ...prevState.datasource, [attr]: value } }), + this.onDatasourceChange(datasource), + ); } setColumns(obj) { diff --git a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx index 1e49bc6a643cc..5114fd8496400 100644 --- a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx +++ b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx @@ -88,40 +88,40 @@ export default class AdhocMetricEditPopover extends React.Component { } onColumnChange(column) { - this.setState({ - adhocMetric: this.state.adhocMetric.duplicateWith({ + this.setState(prevState => ({ + adhocMetric: prevState.adhocMetric.duplicateWith({ column, expressionType: EXPRESSION_TYPES.SIMPLE, }), - }); + })); } onAggregateChange(aggregate) { // we construct this object explicitly to overwrite the value in the case aggregate is null - this.setState({ - adhocMetric: this.state.adhocMetric.duplicateWith({ + this.setState(prevState => ({ + adhocMetric: prevState.adhocMetric.duplicateWith({ aggregate, expressionType: EXPRESSION_TYPES.SIMPLE, }), - }); + })); } onSqlExpressionChange(sqlExpression) { - this.setState({ - adhocMetric: this.state.adhocMetric.duplicateWith({ + this.setState(prevState => ({ + adhocMetric: prevState.adhocMetric.duplicateWith({ sqlExpression, expressionType: EXPRESSION_TYPES.SQL, }), - }); + })); } onLabelChange(e) { - this.setState({ - adhocMetric: this.state.adhocMetric.duplicateWith({ + this.setState(prevState => ({ + adhocMetric: prevState.adhocMetric.duplicateWith({ label: e.target.value, hasCustomLabel: true, }), - }); + })); } onDragDown(e) { diff --git a/superset-frontend/src/explore/components/ControlPanelSection.jsx b/superset-frontend/src/explore/components/ControlPanelSection.jsx index 9913b78034410..71cd56ae2932a 100644 --- a/superset-frontend/src/explore/components/ControlPanelSection.jsx +++ b/superset-frontend/src/explore/components/ControlPanelSection.jsx @@ -44,7 +44,7 @@ export default class ControlPanelSection extends React.Component { } toggleExpand() { - this.setState({ expanded: !this.state.expanded }); + this.setState(prevState => ({ expanded: !prevState.expanded })); } renderHeader() { diff --git a/superset-frontend/src/explore/components/ExploreViewContainer.jsx b/superset-frontend/src/explore/components/ExploreViewContainer.jsx index eedeedaf7df69..7b49e49a84a5e 100644 --- a/superset-frontend/src/explore/components/ExploreViewContainer.jsx +++ b/superset-frontend/src/explore/components/ExploreViewContainer.jsx @@ -281,7 +281,7 @@ class ExploreViewContainer extends React.Component { } toggleModal() { - this.setState({ showModal: !this.state.showModal }); + this.setState(prevState => ({ showModal: !prevState.showModal })); } hasErrors() { diff --git a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx index 49e1fac3137de..cded668bf7434 100644 --- a/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx +++ b/superset-frontend/src/explore/components/controls/AnnotationLayer.jsx @@ -333,7 +333,7 @@ export default class AnnotationLayer extends React.PureComponent { annotation.color = annotation.color === AUTOMATIC_COLOR ? null : annotation.color; this.props.addAnnotationLayer(annotation); - this.setState({ isNew: false, oldName: this.state.name }); + this.setState(prevState => ({ isNew: false, oldName: prevState.name })); } } diff --git a/superset-frontend/src/explore/components/controls/BoundsControl.jsx b/superset-frontend/src/explore/components/controls/BoundsControl.jsx index 5c7c567f33fbb..22ecd40dfadf5 100644 --- a/superset-frontend/src/explore/components/controls/BoundsControl.jsx +++ b/superset-frontend/src/explore/components/controls/BoundsControl.jsx @@ -48,18 +48,18 @@ export default class BoundsControl extends React.Component { onMinChange(event) { this.setState( - { - minMax: [event.target.value, this.state.minMax[1]], - }, + prevState => ({ + minMax: [event.target.value, prevState.minMax[1]], + }), this.onChange, ); } onMaxChange(event) { this.setState( - { - minMax: [this.state.minMax[0], event.target.value], - }, + prevState => ({ + minMax: [prevState.minMax[0], event.target.value], + }), this.onChange, ); } diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl.jsx b/superset-frontend/src/explore/components/controls/DateFilterControl.jsx index 9682b7561407a..f49afda54c888 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl.jsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl.jsx @@ -259,14 +259,14 @@ class DateFilterControl extends React.Component { const closeCalendar = (key === 'since' && this.state.sinceViewMode === 'days') || (key === 'until' && this.state.untilViewMode === 'days'); - this.setState({ + this.setState(prevState => ({ type: TYPES.CUSTOM_START_END, [key]: typeof value === 'string' ? value : value.format(MOMENT_FORMAT), - showSinceCalendar: this.state.showSinceCalendar && !closeCalendar, - showUntilCalendar: this.state.showUntilCalendar && !closeCalendar, - sinceViewMode: closeCalendar ? 'days' : this.state.sinceViewMode, - untilViewMode: closeCalendar ? 'days' : this.state.untilViewMode, - }); + showSinceCalendar: prevState.showSinceCalendar && !closeCalendar, + showUntilCalendar: prevState.showUntilCalendar && !closeCalendar, + sinceViewMode: closeCalendar ? 'days' : prevState.sinceViewMode, + untilViewMode: closeCalendar ? 'days' : prevState.untilViewMode, + })); } setTypeCustomRange() { diff --git a/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx b/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx index 6c8edfc4d6900..d7cf050b21508 100644 --- a/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx +++ b/superset-frontend/src/explore/components/controls/FixedOrMetricControl.jsx @@ -90,10 +90,9 @@ export default class FixedOrMetricControl extends React.Component { } toggle() { - const expanded = !this.state.expanded; - this.setState({ - expanded, - }); + this.setState(prevState => ({ + expanded: !prevState.expanded, + })); } render() { diff --git a/superset-frontend/src/explore/components/controls/SpatialControl.jsx b/superset-frontend/src/explore/components/controls/SpatialControl.jsx index 9553200aab5bb..073148be9560b 100644 --- a/superset-frontend/src/explore/components/controls/SpatialControl.jsx +++ b/superset-frontend/src/explore/components/controls/SpatialControl.jsx @@ -114,7 +114,7 @@ export default class SpatialControl extends React.Component { toggleCheckbox() { this.setState( - { reverseCheckbox: !this.state.reverseCheckbox }, + prevState => ({ reverseCheckbox: !prevState.reverseCheckbox }), this.onChange, ); } diff --git a/superset-frontend/src/explore/components/controls/VizTypeControl.jsx b/superset-frontend/src/explore/components/controls/VizTypeControl.jsx index ee1a4bf6188c6..3f1bd2b89b4a0 100644 --- a/superset-frontend/src/explore/components/controls/VizTypeControl.jsx +++ b/superset-frontend/src/explore/components/controls/VizTypeControl.jsx @@ -120,7 +120,7 @@ export default class VizTypeControl extends React.PureComponent { } toggleModal() { - this.setState({ showModal: !this.state.showModal }); + this.setState(prevState => ({ showModal: !prevState.showModal })); } changeSearch(event) { diff --git a/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx b/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx index eb8c4bce7cb3c..a5d33f93a400a 100644 --- a/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx +++ b/superset-frontend/src/visualizations/FilterBox/FilterBox.jsx @@ -176,16 +176,21 @@ class FilterBox extends React.Component { vals = options; } } - const selectedValues = { - ...this.state.selectedValues, - [fltr]: vals, - }; - this.setState({ selectedValues, hasChanged: true }, () => { - if (this.props.instantFiltering) { - this.props.onChange({ [fltr]: vals }, false); - } - }); + this.setState( + prevState => ({ + selectedValues: { + ...prevState.selectedValues, + [fltr]: vals, + }, + hasChanged: true, + }), + () => { + if (this.props.instantFiltering) { + this.props.onChange({ [fltr]: vals }, false); + } + }, + ); } /** From 26265a0d391d116ee04963d9547b29aa084f57a4 Mon Sep 17 00:00:00 2001 From: Kamil Gabryjelski Date: Sun, 20 Sep 2020 23:12:36 +0200 Subject: [PATCH 2/2] Move accessing event values out of async functions --- .../src/explore/components/AdhocMetricEditPopover.jsx | 3 ++- .../src/explore/components/controls/BoundsControl.jsx | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx index 5114fd8496400..3e0c465b7f6ea 100644 --- a/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx +++ b/superset-frontend/src/explore/components/AdhocMetricEditPopover.jsx @@ -116,9 +116,10 @@ export default class AdhocMetricEditPopover extends React.Component { } onLabelChange(e) { + const label = e.target.value; this.setState(prevState => ({ adhocMetric: prevState.adhocMetric.duplicateWith({ - label: e.target.value, + label, hasCustomLabel: true, }), })); diff --git a/superset-frontend/src/explore/components/controls/BoundsControl.jsx b/superset-frontend/src/explore/components/controls/BoundsControl.jsx index 22ecd40dfadf5..efdae19a144b5 100644 --- a/superset-frontend/src/explore/components/controls/BoundsControl.jsx +++ b/superset-frontend/src/explore/components/controls/BoundsControl.jsx @@ -47,18 +47,20 @@ export default class BoundsControl extends React.Component { } onMinChange(event) { + const min = event.target.value; this.setState( prevState => ({ - minMax: [event.target.value, prevState.minMax[1]], + minMax: [min, prevState.minMax[1]], }), this.onChange, ); } onMaxChange(event) { + const max = event.target.value; this.setState( prevState => ({ - minMax: [prevState.minMax[0], event.target.value], + minMax: [prevState.minMax[0], max], }), this.onChange, );