From dd82ad4d90077070ecc7bbbe92003a5dab7b27ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B8=85=E5=B1=B1?= <576222103@qq.com> Date: Sun, 11 Dec 2022 19:30:38 +0800 Subject: [PATCH 1/3] fix(antd/transfer): transfer performance optimization while dataSource is large --- components/_util/transKeys.ts | 25 +++++++++++++++++++++++++ components/transfer/index.tsx | 20 +++++++++++--------- components/transfer/list.tsx | 4 +++- 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 components/_util/transKeys.ts diff --git a/components/_util/transKeys.ts b/components/_util/transKeys.ts new file mode 100644 index 000000000000..5d3a4bdd5e9c --- /dev/null +++ b/components/_util/transKeys.ts @@ -0,0 +1,25 @@ +export type mapItem = { + k: string; + i: number; +}; +export type MapType = Record; + +export const groupKeysMap = (keys: string[]) => { + const map: MapType = {}; + keys.forEach((k, i) => { + map[k] = { k, i }; + }); + return map; +}; +export function groupDisabledKeysMap(dataSource: RecordType) { + const map: MapType = {}; + dataSource.forEach((d, i) => { + if (d.disabled) { + map[d.key] = { + k: d.key, + i, + }; + } + }); + return map; +} diff --git a/components/transfer/index.tsx b/components/transfer/index.tsx index 9ec0a8a91de1..e0dbd38cb910 100644 --- a/components/transfer/index.tsx +++ b/components/transfer/index.tsx @@ -8,6 +8,7 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from '../locale/en_US'; import type { InputStatus } from '../_util/statusUtils'; import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils'; +import { groupKeysMap, groupDisabledKeysMap } from '../_util/transKeys'; import warning from '../_util/warning'; import type { PaginationType } from './interface'; import type { TransferListProps } from './list'; @@ -203,15 +204,16 @@ class Transfer extends React.Com const { targetKeys = [], dataSource = [], onChange } = this.props; const { sourceSelectedKeys, targetSelectedKeys } = this.state; const moveKeys = direction === 'right' ? sourceSelectedKeys : targetSelectedKeys; + const dataSourceDisabledKeysMap = groupDisabledKeysMap(dataSource); + // filter the disabled options - const newMoveKeys = moveKeys.filter( - (key) => !dataSource.some((data) => !!(key === data.key && data.disabled)), - ); + const newMoveKeys = moveKeys.filter((key) => !dataSourceDisabledKeysMap[key]); + const newMoveKeysMap = groupKeysMap(newMoveKeys); // move items to target box const newTargetKeys = direction === 'right' ? newMoveKeys.concat(targetKeys) - : targetKeys.filter((targetKey) => !newMoveKeys.includes(targetKey)); + : targetKeys.filter((targetKey) => !newMoveKeysMap[targetKey]); // empty checked keys const oppositeDirection = direction === 'right' ? 'left' : 'right'; @@ -232,8 +234,9 @@ class Transfer extends React.Com // Merge current keys with origin key mergedCheckedKeys = Array.from(new Set([...prevKeys, ...selectedKeys])); } else { + const selectedKeysMap = groupKeysMap(selectedKeys); // Remove current keys from origin keys - mergedCheckedKeys = prevKeys.filter((key) => !selectedKeys.includes(key)); + mergedCheckedKeys = prevKeys.filter((key) => !selectedKeysMap[key]); } this.handleSelectChange(direction, mergedCheckedKeys); @@ -341,6 +344,7 @@ class Transfer extends React.Com const leftDataSource: KeyWise[] = []; const rightDataSource: KeyWise[] = new Array(targetKeys.length); + const targetKeysMap = groupKeysMap(targetKeys); dataSource.forEach((record: KeyWise) => { if (rowKey) { record = { @@ -348,12 +352,10 @@ class Transfer extends React.Com key: rowKey(record), }; } - // rightDataSource should be ordered by targetKeys // leftDataSource should be ordered by dataSource - const indexOfKey = targetKeys.indexOf(record.key); - if (indexOfKey !== -1) { - rightDataSource[indexOfKey] = record; + if (targetKeysMap[record.key]) { + rightDataSource[targetKeysMap[record.key].i] = record; } else { leftDataSource.push(record); } diff --git a/components/transfer/list.tsx b/components/transfer/list.tsx index 769b5e3bd66f..4a6bcf590a46 100644 --- a/components/transfer/list.tsx +++ b/components/transfer/list.tsx @@ -6,6 +6,7 @@ import Checkbox from '../checkbox'; import Dropdown from '../dropdown'; import type { MenuProps } from '../menu'; import { isValidElement } from '../_util/reactNode'; +import { groupKeysMap } from '../_util/transKeys'; import type { KeyWiseTransferItem, RenderResult, @@ -103,7 +104,8 @@ export default class TransferList< if (checkedKeys.length === 0) { return 'none'; } - if (filteredItems.every((item) => checkedKeys.includes(item.key) || !!item.disabled)) { + const keysMap = groupKeysMap(checkedKeys); + if (filteredItems.every((item) => keysMap[item.key] || !!item.disabled)) { return 'all'; } return 'part'; From dcf5ad930301222ba72215640e2eaff30319482f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B8=85=E5=B1=B1?= <576222103@qq.com> Date: Tue, 13 Dec 2022 16:54:37 +0800 Subject: [PATCH 2/3] fix(antd/transfer): unified function format of transKeys util file --- components/_util/transKeys.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/_util/transKeys.ts b/components/_util/transKeys.ts index 5d3a4bdd5e9c..9dbfec5977d1 100644 --- a/components/_util/transKeys.ts +++ b/components/_util/transKeys.ts @@ -11,7 +11,7 @@ export const groupKeysMap = (keys: string[]) => { }); return map; }; -export function groupDisabledKeysMap(dataSource: RecordType) { +export const groupDisabledKeysMap = (dataSource: RecordType) => { const map: MapType = {}; dataSource.forEach((d, i) => { if (d.disabled) { @@ -22,4 +22,4 @@ export function groupDisabledKeysMap(dataSource: Recor } }); return map; -} +}; From 05cdf0d95f33cf2057827087af6ba11eed865ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B8=85=E5=B1=B1?= <576222103@qq.com> Date: Fri, 23 Dec 2022 10:10:10 +0800 Subject: [PATCH 3/3] fix(antd/transfer): transKeys Map Structure Adjustment --- components/_util/transKeys.ts | 23 +++++++---------------- components/transfer/index.tsx | 10 +++++----- components/transfer/list.tsx | 4 ++-- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/components/_util/transKeys.ts b/components/_util/transKeys.ts index 9dbfec5977d1..24e48be2c80c 100644 --- a/components/_util/transKeys.ts +++ b/components/_util/transKeys.ts @@ -1,24 +1,15 @@ -export type mapItem = { - k: string; - i: number; -}; -export type MapType = Record; - export const groupKeysMap = (keys: string[]) => { - const map: MapType = {}; - keys.forEach((k, i) => { - map[k] = { k, i }; + const map = new Map(); + keys.forEach((key, index) => { + map.set(key, index); }); return map; }; export const groupDisabledKeysMap = (dataSource: RecordType) => { - const map: MapType = {}; - dataSource.forEach((d, i) => { - if (d.disabled) { - map[d.key] = { - k: d.key, - i, - }; + const map = new Map(); + dataSource.forEach(({ disabled, key }, index) => { + if (disabled) { + map.set(key, index); } }); return map; diff --git a/components/transfer/index.tsx b/components/transfer/index.tsx index e0dbd38cb910..bb796ebb713a 100644 --- a/components/transfer/index.tsx +++ b/components/transfer/index.tsx @@ -207,13 +207,13 @@ class Transfer extends React.Com const dataSourceDisabledKeysMap = groupDisabledKeysMap(dataSource); // filter the disabled options - const newMoveKeys = moveKeys.filter((key) => !dataSourceDisabledKeysMap[key]); + const newMoveKeys = moveKeys.filter((key) => !dataSourceDisabledKeysMap.has(key)); const newMoveKeysMap = groupKeysMap(newMoveKeys); // move items to target box const newTargetKeys = direction === 'right' ? newMoveKeys.concat(targetKeys) - : targetKeys.filter((targetKey) => !newMoveKeysMap[targetKey]); + : targetKeys.filter((targetKey) => !newMoveKeysMap.has(targetKey)); // empty checked keys const oppositeDirection = direction === 'right' ? 'left' : 'right'; @@ -236,7 +236,7 @@ class Transfer extends React.Com } else { const selectedKeysMap = groupKeysMap(selectedKeys); // Remove current keys from origin keys - mergedCheckedKeys = prevKeys.filter((key) => !selectedKeysMap[key]); + mergedCheckedKeys = prevKeys.filter((key) => !selectedKeysMap.has(key)); } this.handleSelectChange(direction, mergedCheckedKeys); @@ -354,8 +354,8 @@ class Transfer extends React.Com } // rightDataSource should be ordered by targetKeys // leftDataSource should be ordered by dataSource - if (targetKeysMap[record.key]) { - rightDataSource[targetKeysMap[record.key].i] = record; + if (targetKeysMap.has(record.key)) { + rightDataSource[targetKeysMap.get(record.key)!] = record; } else { leftDataSource.push(record); } diff --git a/components/transfer/list.tsx b/components/transfer/list.tsx index 4a6bcf590a46..6e62cae74b93 100644 --- a/components/transfer/list.tsx +++ b/components/transfer/list.tsx @@ -104,8 +104,8 @@ export default class TransferList< if (checkedKeys.length === 0) { return 'none'; } - const keysMap = groupKeysMap(checkedKeys); - if (filteredItems.every((item) => keysMap[item.key] || !!item.disabled)) { + const checkedKeysMap = groupKeysMap(checkedKeys); + if (filteredItems.every((item) => checkedKeysMap.has(item.key) || !!item.disabled)) { return 'all'; } return 'part';