Skip to content

Commit 51d8e13

Browse files
perf: optimize display value label lookup
1 parent 8691e30 commit 51d8e13

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

‎src/TreeSelect.tsx‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,18 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
412412
// Convert to value and filled with label
413413
const values = displayKeys.map(key => keyEntities[key]?.node?.[mergedFieldNames.value] ?? key);
414414

415+
// Avoid an O(displayed values × selected values) lookup
416+
const labeledValueMap = new Map<SafeKey, LabeledValueType>();
417+
rawLabeledValues.forEach(item => {
418+
// Match `find` by keeping the first entry when controlled values contain duplicates.
419+
if (!labeledValueMap.has(item.value)) {
420+
labeledValueMap.set(item.value, item);
421+
}
422+
});
423+
415424
// Back fill with origin label
416425
const labeledValues = values.map(val => {
417-
const targetItem = rawLabeledValues.find(item => item.value === val);
426+
const targetItem = labeledValueMap.get(val);
418427
const label = labelInValue ? targetItem?.label : treeTitleRender?.(targetItem);
419428
return {
420429
value: val,

‎tests/Select.checkable.spec.tsx‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,30 @@ describe('TreeSelect.checkable', () => {
531531
expect(getSelectionText(container, 0)).toEqual('0-0');
532532
});
533533

534+
it('preserves labels with SHOW_ALL', () => {
535+
const { container } = render(
536+
<TreeSelect
537+
treeCheckable
538+
showCheckedStrategy={SHOW_ALL}
539+
labelInValue
540+
value={[
541+
{ value: 'parent', label: 'Custom parent' },
542+
{ value: 'child', label: 'Custom child' },
543+
]}
544+
>
545+
<TreeNode key="parent" value="parent" title="Parent">
546+
<TreeNode key="child" value="child" title="Child" />
547+
</TreeNode>
548+
</TreeSelect>,
549+
);
550+
551+
expect(getSelections(container)).toHaveLength(2);
552+
expect([getSelectionText(container, 0), getSelectionText(container, 1)]).toEqual([
553+
'Custom parent',
554+
'Custom child',
555+
]);
556+
});
557+
534558
// https://github.com/ant-design/ant-design/issues/38126
535559
it('keep label when not in options', () => {
536560
const onChange = jest.fn();

0 commit comments

Comments
 (0)