Skip to content

Commit bac7b01

Browse files
authored
feat: Column support shouldCellUpdate (#466)
* support shouldCellUpdate * add test case
1 parent 626b147 commit bac7b01

File tree

5 files changed

+59
-2
lines changed

5 files changed

+59
-2
lines changed

.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ module.exports = {
1616
'import/no-named-as-default-member': 0,
1717
'jsx-a11y/label-has-for': 0,
1818
'jsx-a11y/label-has-associated-control': 0,
19+
'jsx-a11y/control-has-associated-label': 0,
1920
},
2021
};

src/Body/BodyRow.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ function BodyRow<RecordType extends { children?: RecordType[] }>(props: BodyRowP
158158
index={index}
159159
dataIndex={dataIndex}
160160
render={render}
161+
shouldCellUpdate={column.shouldCellUpdate}
161162
{...fixedInfo}
162163
appendNode={appendCellNode}
163164
additionalProps={additionalCellProps}

src/Cell/index.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export interface CellProps<RecordType extends DefaultRecordType> {
4141
ellipsis?: boolean;
4242
align?: AlignType;
4343

44+
shouldCellUpdate?: (record: RecordType) => boolean;
45+
4446
// Fixed
4547
fixLeft?: number | false;
4648
fixRight?: number | false;
@@ -197,7 +199,15 @@ function Cell<RecordType extends DefaultRecordType>(
197199
);
198200
}
199201

200-
const RefCell = React.forwardRef(Cell);
202+
const RefCell = React.forwardRef<any, CellProps<any>>(Cell);
201203
RefCell.displayName = 'Cell';
202204

203-
export default RefCell;
205+
const MemoCell = React.memo(RefCell, (_, next: CellProps<any>) => {
206+
if (next.shouldCellUpdate) {
207+
return !next.shouldCellUpdate(next.record);
208+
}
209+
210+
return false;
211+
});
212+
213+
export default MemoCell;

src/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export interface ColumnType<RecordType> extends ColumnSharedType<RecordType> {
7979
record: RecordType,
8080
index: number,
8181
) => React.ReactNode | RenderedCell<RecordType>;
82+
shouldCellUpdate?: (record: RecordType) => boolean;
8283
rowSpan?: number;
8384
width?: number | string;
8485
onCell?: GetComponentProps<RecordType>;

tests/Table.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,4 +925,48 @@ describe('Table.Basic', () => {
925925
);
926926
}).not.toThrow();
927927
});
928+
929+
it('shouldCellUpdate', () => {
930+
const record = { key: 1 };
931+
let shouldUpdate = false;
932+
let renderTimes = 0;
933+
934+
const Demo = () => {
935+
const [, forceUpdate] = React.useState({});
936+
937+
return (
938+
<>
939+
<Table
940+
data={[record]}
941+
columns={[
942+
{
943+
dataIndex: 'key',
944+
shouldCellUpdate: () => shouldUpdate,
945+
render() {
946+
renderTimes += 1;
947+
return null;
948+
},
949+
},
950+
]}
951+
/>
952+
<button
953+
type="button"
954+
onClick={() => {
955+
forceUpdate({});
956+
}}
957+
/>
958+
</>
959+
);
960+
};
961+
962+
const wrapper = mount(<Demo />);
963+
renderTimes = 0;
964+
965+
wrapper.find('button').simulate('click');
966+
expect(renderTimes).toEqual(0);
967+
968+
shouldUpdate = true;
969+
wrapper.find('button').simulate('click');
970+
expect(renderTimes).toEqual(1);
971+
});
928972
});

0 commit comments

Comments
 (0)