diff --git a/src/generate.tsx b/src/generate.tsx index e06ad2493..b14e25cd2 100644 --- a/src/generate.tsx +++ b/src/generate.tsx @@ -371,7 +371,7 @@ export default function generateSelector< React.useImperativeHandle(ref, () => ({ focus: selectorRef.current.focus, blur: selectorRef.current.blur, - scrollTo: listRef.current?.scrollTo, + scrollTo: listRef.current?.scrollTo as ScrollTo, })); // ============================= Value ============================== @@ -380,7 +380,9 @@ export default function generateSelector< }); /** Unique raw values */ - const mergedRawValue = useMemo( + const [mergedRawValue, mergedValueMap] = useMemo< + [RawValueType[], Map] + >( () => toInnerValue(mergedValue, { labelInValue: mergedLabelInValue, @@ -431,7 +433,7 @@ export default function generateSelector< [mergedOptions], ); - const getValueOption = useCacheOptions(mergedRawValue, mergedFlattenOptions); + const getValueOption = useCacheOptions(mergedFlattenOptions); // Display options for OptionList const displayOptions = useMemo(() => { @@ -476,7 +478,7 @@ export default function generateSelector< const valueOptions = getValueOption([val]); const displayValue = getLabeledValue(val, { options: valueOptions, - prevValue: mergedValue, + prevValueMap: mergedValueMap, labelInValue: mergedLabelInValue, optionLabelProp: mergedOptionLabelProp, }); @@ -511,7 +513,7 @@ export default function generateSelector< const selectValue = (mergedLabelInValue ? getLabeledValue(newValue, { options: newValueOption, - prevValue: mergedValue, + prevValueMap: mergedValueMap, labelInValue: mergedLabelInValue, optionLabelProp: mergedOptionLabelProp, }) @@ -546,7 +548,7 @@ export default function generateSelector< labelInValue: mergedLabelInValue, options: newRawValuesOptions, getLabeledValue, - prevValue: mergedValue, + prevValueMap: mergedValueMap, optionLabelProp: mergedOptionLabelProp, }); diff --git a/src/hooks/useCacheOptions.ts b/src/hooks/useCacheOptions.ts index e8677d06a..028631d88 100644 --- a/src/hooks/useCacheOptions.ts +++ b/src/hooks/useCacheOptions.ts @@ -8,7 +8,7 @@ export default function useCacheOptions< key?: Key; disabled?: boolean; }[] ->(values: RawValueType[], options: FlattenOptionsType) { +>(options: FlattenOptionsType) { const prevOptionMapRef = React.useRef[number]>>( null, ); @@ -22,7 +22,7 @@ export default function useCacheOptions< map.set(value, item); }); return map; - }, [values, options]); + }, [options]); prevOptionMapRef.current = optionMap; diff --git a/src/interface/generator.ts b/src/interface/generator.ts index 490636ce6..55e14c230 100644 --- a/src/interface/generator.ts +++ b/src/interface/generator.ts @@ -38,7 +38,7 @@ export type GetLabeledValue = ( value: RawValueType, config: { options: FOT; - prevValue: DefaultValueType; + prevValueMap: Map; labelInValue: boolean; optionLabelProp: string; }, diff --git a/src/utils/commonUtil.ts b/src/utils/commonUtil.ts index a4a2d2ee3..e60d8294d 100644 --- a/src/utils/commonUtil.ts +++ b/src/utils/commonUtil.ts @@ -19,20 +19,26 @@ export function toArray(value: T | T[]): T[] { export function toInnerValue( value: DefaultValueType, { labelInValue, combobox }: { labelInValue: boolean; combobox: boolean }, -): RawValueType[] { +): [RawValueType[], Map] { + const valueMap = new Map(); + if (value === undefined || (value === '' && combobox)) { - return []; + return [[], valueMap]; } const values = Array.isArray(value) ? value : [value]; + let rawValues = values as RawValueType[]; if (labelInValue) { - return (values as LabelValueType[]).map( - ({ key, value: val }: LabelValueType) => (val !== undefined ? val : key), - ); + rawValues = (values as LabelValueType[]).map((itemValue: LabelValueType) => { + const { key, value: val } = itemValue; + const finalVal = val !== undefined ? val : key; + valueMap.set(finalVal, itemValue); + return finalVal; + }); } - return values as RawValueType[]; + return [rawValues, valueMap]; } /** @@ -43,7 +49,7 @@ export function toOuterValues( { optionLabelProp, labelInValue, - prevValue, + prevValueMap, options, getLabeledValue, }: { @@ -51,7 +57,7 @@ export function toOuterValues( labelInValue: boolean; getLabeledValue: GetLabeledValue; options: FOT; - prevValue: DefaultValueType; + prevValueMap: Map; }, ): RawValueType[] | LabelValueType[] { let values: DefaultValueType = valueList; @@ -60,7 +66,7 @@ export function toOuterValues( values = values.map(val => getLabeledValue(val, { options, - prevValue, + prevValueMap, labelInValue, optionLabelProp, }), @@ -77,11 +83,7 @@ export function removeLastEnabledValue< const newValues = [...values]; let removeIndex: number; - for ( - removeIndex = measureValues.length - 1; - removeIndex >= 0; - removeIndex -= 1 - ) { + for (removeIndex = measureValues.length - 1; removeIndex >= 0; removeIndex -= 1) { if (!measureValues[removeIndex].disabled) { break; } @@ -101,9 +103,7 @@ export function removeLastEnabledValue< } export const isClient = - typeof window !== 'undefined' && - window.document && - window.document.documentElement; + typeof window !== 'undefined' && window.document && window.document.documentElement; /** Is client side and not jsdom */ export const isBrowserClient = process.env.NODE_ENV !== 'test' && isClient; diff --git a/src/utils/valueUtil.ts b/src/utils/valueUtil.ts index 07e131faf..73862010b 100644 --- a/src/utils/valueUtil.ts +++ b/src/utils/valueUtil.ts @@ -119,24 +119,14 @@ export function findValueOption( export const getLabeledValue: GetLabeledValue = ( value, - { options, prevValue, labelInValue, optionLabelProp }, + { options, prevValueMap, labelInValue, optionLabelProp }, ) => { const item = findValueOption([value], options)[0]; const result: LabelValueType = { value, }; - let prevValItem: LabelValueType; - const prevValues = toArray(prevValue); - if (labelInValue) { - prevValItem = prevValues.find((prevItem: LabelValueType) => { - if (typeof prevItem === 'object' && 'value' in prevItem) { - return prevItem.value === value; - } - // [Legacy] Support `key` as `value` - return prevItem.key === value; - }) as LabelValueType; - } + const prevValItem: LabelValueType = labelInValue ? prevValueMap.get(value) : undefined; if (prevValItem && typeof prevValItem === 'object' && 'label' in prevValItem) { result.label = prevValItem.label;