diff --git a/.eslintrc.js b/.eslintrc.js index 5b4f4d681..dc13f593f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,5 +16,6 @@ module.exports = { 'import/no-named-as-default-member': 0, 'jsx-a11y/label-has-for': 0, 'jsx-a11y/label-has-associated-control': 0, + 'jsx-a11y/control-has-associated-label': 0, }, }; diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index 8952b4964..a1753da58 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -158,6 +158,7 @@ function BodyRow(props: BodyRowP index={index} dataIndex={dataIndex} render={render} + shouldCellUpdate={column.shouldCellUpdate} {...fixedInfo} appendNode={appendCellNode} additionalProps={additionalCellProps} diff --git a/src/Cell/index.tsx b/src/Cell/index.tsx index fe48ae44e..48b433ac9 100644 --- a/src/Cell/index.tsx +++ b/src/Cell/index.tsx @@ -41,6 +41,8 @@ export interface CellProps { ellipsis?: boolean; align?: AlignType; + shouldCellUpdate?: (record: RecordType) => boolean; + // Fixed fixLeft?: number | false; fixRight?: number | false; @@ -197,7 +199,15 @@ function Cell( ); } -const RefCell = React.forwardRef(Cell); +const RefCell = React.forwardRef>(Cell); RefCell.displayName = 'Cell'; -export default RefCell; +const MemoCell = React.memo(RefCell, (_, next: CellProps) => { + if (next.shouldCellUpdate) { + return !next.shouldCellUpdate(next.record); + } + + return false; +}); + +export default MemoCell; diff --git a/src/interface.ts b/src/interface.ts index 7d6b31277..3f4ac79ca 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -79,6 +79,7 @@ export interface ColumnType extends ColumnSharedType { record: RecordType, index: number, ) => React.ReactNode | RenderedCell; + shouldCellUpdate?: (record: RecordType) => boolean; rowSpan?: number; width?: number | string; onCell?: GetComponentProps; diff --git a/tests/Table.spec.js b/tests/Table.spec.js index 718c3765c..9f4b3e9c0 100644 --- a/tests/Table.spec.js +++ b/tests/Table.spec.js @@ -925,4 +925,48 @@ describe('Table.Basic', () => { ); }).not.toThrow(); }); + + it('shouldCellUpdate', () => { + const record = { key: 1 }; + let shouldUpdate = false; + let renderTimes = 0; + + const Demo = () => { + const [, forceUpdate] = React.useState({}); + + return ( + <> + shouldUpdate, + render() { + renderTimes += 1; + return null; + }, + }, + ]} + /> +