fix(antd/transfer): transfer performance optimization while dataSourc… (#39465)

* fix(antd/transfer): transfer performance optimization while dataSource is large

* fix(antd/transfer): unified function format of transKeys util file

* fix(antd/transfer): transKeys Map Structure Adjustment
This commit is contained in:
sea、lucky 2022-12-25 15:21:21 +08:00 committed by GitHub
parent af012dfb81
commit f488cb871b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 10 deletions

View File

@ -0,0 +1,16 @@
export const groupKeysMap = (keys: string[]) => {
const map = new Map<string, number>();
keys.forEach((key, index) => {
map.set(key, index);
});
return map;
};
export const groupDisabledKeysMap = <RecordType extends any[]>(dataSource: RecordType) => {
const map = new Map<string, number>();
dataSource.forEach(({ disabled, key }, index) => {
if (disabled) {
map.set(key, index);
}
});
return map;
};

View File

@ -8,6 +8,7 @@ import LocaleReceiver from '../locale/LocaleReceiver';
import defaultLocale from '../locale/en_US'; import defaultLocale from '../locale/en_US';
import type { InputStatus } from '../_util/statusUtils'; import type { InputStatus } from '../_util/statusUtils';
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
import { groupKeysMap, groupDisabledKeysMap } from '../_util/transKeys';
import warning from '../_util/warning'; import warning from '../_util/warning';
import type { PaginationType } from './interface'; import type { PaginationType } from './interface';
import type { TransferListProps } from './list'; import type { TransferListProps } from './list';
@ -203,15 +204,16 @@ class Transfer<RecordType extends TransferItem = TransferItem> extends React.Com
const { targetKeys = [], dataSource = [], onChange } = this.props; const { targetKeys = [], dataSource = [], onChange } = this.props;
const { sourceSelectedKeys, targetSelectedKeys } = this.state; const { sourceSelectedKeys, targetSelectedKeys } = this.state;
const moveKeys = direction === 'right' ? sourceSelectedKeys : targetSelectedKeys; const moveKeys = direction === 'right' ? sourceSelectedKeys : targetSelectedKeys;
const dataSourceDisabledKeysMap = groupDisabledKeysMap(dataSource);
// filter the disabled options // filter the disabled options
const newMoveKeys = moveKeys.filter( const newMoveKeys = moveKeys.filter((key) => !dataSourceDisabledKeysMap.has(key));
(key) => !dataSource.some((data) => !!(key === data.key && data.disabled)), const newMoveKeysMap = groupKeysMap(newMoveKeys);
);
// move items to target box // move items to target box
const newTargetKeys = const newTargetKeys =
direction === 'right' direction === 'right'
? newMoveKeys.concat(targetKeys) ? newMoveKeys.concat(targetKeys)
: targetKeys.filter((targetKey) => !newMoveKeys.includes(targetKey)); : targetKeys.filter((targetKey) => !newMoveKeysMap.has(targetKey));
// empty checked keys // empty checked keys
const oppositeDirection = direction === 'right' ? 'left' : 'right'; const oppositeDirection = direction === 'right' ? 'left' : 'right';
@ -232,8 +234,9 @@ class Transfer<RecordType extends TransferItem = TransferItem> extends React.Com
// Merge current keys with origin key // Merge current keys with origin key
mergedCheckedKeys = Array.from(new Set<string>([...prevKeys, ...selectedKeys])); mergedCheckedKeys = Array.from(new Set<string>([...prevKeys, ...selectedKeys]));
} else { } else {
const selectedKeysMap = groupKeysMap(selectedKeys);
// Remove current keys from origin keys // Remove current keys from origin keys
mergedCheckedKeys = prevKeys.filter((key) => !selectedKeys.includes(key)); mergedCheckedKeys = prevKeys.filter((key) => !selectedKeysMap.has(key));
} }
this.handleSelectChange(direction, mergedCheckedKeys); this.handleSelectChange(direction, mergedCheckedKeys);
@ -341,6 +344,7 @@ class Transfer<RecordType extends TransferItem = TransferItem> extends React.Com
const leftDataSource: KeyWise<RecordType>[] = []; const leftDataSource: KeyWise<RecordType>[] = [];
const rightDataSource: KeyWise<RecordType>[] = new Array(targetKeys.length); const rightDataSource: KeyWise<RecordType>[] = new Array(targetKeys.length);
const targetKeysMap = groupKeysMap(targetKeys);
dataSource.forEach((record: KeyWise<RecordType>) => { dataSource.forEach((record: KeyWise<RecordType>) => {
if (rowKey) { if (rowKey) {
record = { record = {
@ -348,12 +352,10 @@ class Transfer<RecordType extends TransferItem = TransferItem> extends React.Com
key: rowKey(record), key: rowKey(record),
}; };
} }
// rightDataSource should be ordered by targetKeys // rightDataSource should be ordered by targetKeys
// leftDataSource should be ordered by dataSource // leftDataSource should be ordered by dataSource
const indexOfKey = targetKeys.indexOf(record.key); if (targetKeysMap.has(record.key)) {
if (indexOfKey !== -1) { rightDataSource[targetKeysMap.get(record.key)!] = record;
rightDataSource[indexOfKey] = record;
} else { } else {
leftDataSource.push(record); leftDataSource.push(record);
} }

View File

@ -6,6 +6,7 @@ import Checkbox from '../checkbox';
import Dropdown from '../dropdown'; import Dropdown from '../dropdown';
import type { MenuProps } from '../menu'; import type { MenuProps } from '../menu';
import { isValidElement } from '../_util/reactNode'; import { isValidElement } from '../_util/reactNode';
import { groupKeysMap } from '../_util/transKeys';
import type { import type {
KeyWiseTransferItem, KeyWiseTransferItem,
RenderResult, RenderResult,
@ -103,7 +104,8 @@ export default class TransferList<
if (checkedKeys.length === 0) { if (checkedKeys.length === 0) {
return 'none'; return 'none';
} }
if (filteredItems.every((item) => checkedKeys.includes(item.key) || !!item.disabled)) { const checkedKeysMap = groupKeysMap(checkedKeys);
if (filteredItems.every((item) => checkedKeysMap.has(item.key) || !!item.disabled)) {
return 'all'; return 'all';
} }
return 'part'; return 'part';