diff --git a/components/grid/hooks/useBreakpoint.tsx b/components/grid/hooks/useBreakpoint.tsx index ec34395904..519bd2d470 100644 --- a/components/grid/hooks/useBreakpoint.tsx +++ b/components/grid/hooks/useBreakpoint.tsx @@ -1,18 +1,23 @@ -import { useEffect, useState } from 'react'; +import { useEffect, useRef } from 'react'; +import useForceUpdate from '../../_util/hooks/useForceUpdate'; import ResponsiveObserve, { ScreenMap } from '../../_util/responsiveObserve'; -function useBreakpoint(): ScreenMap { - const [screens, setScreens] = useState({}); +function useBreakpoint(refreshOnChange: boolean = true): ScreenMap { + const screensRef = useRef({}); + const forceUpdate = useForceUpdate(); useEffect(() => { const token = ResponsiveObserve.subscribe(supportScreens => { - setScreens(supportScreens); + screensRef.current = supportScreens; + if (refreshOnChange) { + forceUpdate(); + } }); return () => ResponsiveObserve.unsubscribe(token); }, []); - return screens; + return screensRef.current; } export default useBreakpoint; diff --git a/components/table/Table.tsx b/components/table/Table.tsx index f409d30c5c..aed6bb309e 100644 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -139,15 +139,25 @@ function InternalTable( '`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.', ); - const screens = useBreakpoint(); + const baseColumns = React.useMemo( + () => columns || convertChildrenToColumns(children), + [columns, children], + ); + const needResponsive = React.useMemo( + () => baseColumns.some((col: ColumnType) => col.responsive), + [baseColumns], + ); + + const screens = useBreakpoint(needResponsive); + const mergedColumns = React.useMemo(() => { const matched = new Set(Object.keys(screens).filter((m: Breakpoint) => screens[m])); - return (columns || convertChildrenToColumns(children)).filter( + return baseColumns.filter( (c: ColumnType) => !c.responsive || c.responsive.some((r: Breakpoint) => matched.has(r)), ); - }, [children, columns, screens]); + }, [baseColumns, screens]); const tableProps = omit(props, ['className', 'style', 'columns']) as TableProps; diff --git a/components/table/__tests__/Table.filter.test.js b/components/table/__tests__/Table.filter.test.js index 9aeeed49d4..7f93412439 100644 --- a/components/table/__tests__/Table.filter.test.js +++ b/components/table/__tests__/Table.filter.test.js @@ -1100,7 +1100,7 @@ describe('Table.filter', () => { it('should support getPopupContainer', () => { const getPopupContainer = jest.fn(node => node.parentNode); - const wrapper = mount( + mount( createTable({ columns: [ { @@ -1111,13 +1111,14 @@ describe('Table.filter', () => { getPopupContainer, }), ); - expect(wrapper.render()).toMatchSnapshot(); expect(getPopupContainer).toHaveBeenCalled(); }); it('should support getPopupContainer from ConfigProvider', () => { - const wrapper = mount( - node.parentNode}> + const getPopupContainer = jest.fn(node => node.parentNode); + + mount( + {createTable({ columns: [ { @@ -1128,7 +1129,7 @@ describe('Table.filter', () => { })} , ); - expect(wrapper.render()).toMatchSnapshot(); + expect(getPopupContainer).toHaveBeenCalled(); }); it('pass visible prop to filterDropdown', () => { diff --git a/components/table/__tests__/__snapshots__/Table.filter.test.js.snap b/components/table/__tests__/__snapshots__/Table.filter.test.js.snap index be83e86870..c01f5d3957 100644 --- a/components/table/__tests__/__snapshots__/Table.filter.test.js.snap +++ b/components/table/__tests__/__snapshots__/Table.filter.test.js.snap @@ -509,507 +509,3 @@ exports[`Table.filter renders filter correctly 1`] = ` exports[`Table.filter renders menu correctly 1`] = `
`; exports[`Table.filter renders radio filter correctly 1`] = `
`; - -exports[`Table.filter should support getPopupContainer 1`] = ` -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
- - Name - - - - - - -
-
-
- - -
-
-
-
-
-
- Jack -
- Lucy -
- Tom -
- Jerry -
-
-
-
-
-
-
-`; - -exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] = ` -
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
-
- - Name - - - - - - -
-
-
- - -
-
-
-
-
-
- Jack -
- Lucy -
- Tom -
- Jerry -
-
-
-
-
-
-
-`; diff --git a/components/table/hooks/useSelection.tsx b/components/table/hooks/useSelection.tsx index aa0898447d..582a9b989c 100644 --- a/components/table/hooks/useSelection.tsx +++ b/components/table/hooks/useSelection.tsx @@ -33,6 +33,8 @@ export const SELECTION_ALL = 'SELECT_ALL' as const; export const SELECTION_INVERT = 'SELECT_INVERT' as const; export const SELECTION_NONE = 'SELECT_NONE' as const; +const EMPTY_LIST: React.Key[] = []; + interface UseSelectionConfig { prefixCls: string; pageData: RecordType[]; @@ -108,7 +110,7 @@ export default function useSelection( // ========================= Keys ========================= const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState( - selectedRowKeys || defaultSelectedRowKeys || [], + selectedRowKeys || defaultSelectedRowKeys || EMPTY_LIST, { value: selectedRowKeys, }, @@ -215,7 +217,7 @@ export default function useSelection( // Reset if rowSelection reset React.useEffect(() => { if (!rowSelection) { - setMergedSelectedKeys([]); + setMergedSelectedKeys(EMPTY_LIST); } }, [!!rowSelection]);