diff --git a/superset-frontend/src/dashboard/components/gridComponents/Column.jsx b/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
index d11937ab176ab..71c1892f3b887 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Column.jsx
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { PureComponent, Fragment } from 'react';
+import { Fragment, useCallback, useState, useMemo, memo } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { css, styled, t } from '@superset-ui/core';
@@ -119,203 +119,219 @@ const emptyColumnContentStyles = theme => css`
color: ${theme.colors.text.label};
`;
-class Column extends PureComponent {
- constructor(props) {
- super(props);
- this.state = {
- isFocused: false,
- };
- this.handleChangeBackground = this.handleUpdateMeta.bind(
- this,
- 'background',
- );
- this.handleChangeFocus = this.handleChangeFocus.bind(this);
- this.handleDeleteComponent = this.handleDeleteComponent.bind(this);
- }
+const Column = props => {
+ const {
+ component: columnComponent,
+ parentComponent,
+ index,
+ availableColumnCount,
+ columnWidth,
+ minColumnWidth,
+ depth,
+ onResizeStart,
+ onResize,
+ onResizeStop,
+ handleComponentDrop,
+ editMode,
+ onChangeTab,
+ isComponentVisible,
+ deleteComponent,
+ id,
+ parentId,
+ updateComponents,
+ } = props;
- handleDeleteComponent() {
- const { deleteComponent, id, parentId } = this.props;
+ const [isFocused, setIsFocused] = useState(false);
+
+ const handleDeleteComponent = useCallback(() => {
deleteComponent(id, parentId);
- }
+ }, [deleteComponent, id, parentId]);
- handleChangeFocus(nextFocus) {
- this.setState(() => ({ isFocused: Boolean(nextFocus) }));
- }
+ const handleChangeFocus = useCallback(nextFocus => {
+ setIsFocused(Boolean(nextFocus));
+ }, []);
- handleUpdateMeta(metaKey, nextValue) {
- const { updateComponents, component } = this.props;
- if (nextValue && component.meta[metaKey] !== nextValue) {
- updateComponents({
- [component.id]: {
- ...component,
- meta: {
- ...component.meta,
- [metaKey]: nextValue,
+ const handleChangeBackground = useCallback(
+ nextValue => {
+ const metaKey = 'background';
+ if (nextValue && columnComponent.meta[metaKey] !== nextValue) {
+ updateComponents({
+ [columnComponent.id]: {
+ ...columnComponent,
+ meta: {
+ ...columnComponent.meta,
+ [metaKey]: nextValue,
+ },
},
- },
- });
- }
- }
+ });
+ }
+ },
+ [columnComponent, updateComponents],
+ );
- render() {
- const {
- component: columnComponent,
- parentComponent,
- index,
- availableColumnCount,
- columnWidth,
- minColumnWidth,
- depth,
- onResizeStart,
- onResize,
- onResizeStop,
- handleComponentDrop,
- editMode,
- onChangeTab,
- isComponentVisible,
- } = this.props;
+ const columnItems = useMemo(
+ () => columnComponent.children || [],
+ [columnComponent.children],
+ );
- const columnItems = columnComponent.children || [];
- const backgroundStyle = backgroundStyleOptions.find(
- opt =>
- opt.value ===
- (columnComponent.meta.background || BACKGROUND_TRANSPARENT),
- );
+ const backgroundStyle = backgroundStyleOptions.find(
+ opt =>
+ opt.value === (columnComponent.meta.background || BACKGROUND_TRANSPARENT),
+ );
- return (
-