1
0
Эх сурвалжийг харах

fix: select option never use key in jsx declare usage (#1889)

* fix: select option never use key in jsx declare usage
* fix: avoid change onSelect、onChange params
pointhalo 2 жил өмнө
parent
commit
6a1e34d14d

+ 2 - 0
packages/semi-foundation/select/foundation.ts

@@ -939,6 +939,8 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
         delete newOption._show;
         delete newOption._selected;
         delete newOption._scrollIndex;
+        delete newOption._keyInJsx;
+        
         if ('_keyInOptionList' in newOption) {
             newOption.key = newOption._keyInOptionList;
             delete newOption._keyInOptionList;

+ 18 - 0
packages/semi-ui/select/_story/select.stories.jsx

@@ -3367,3 +3367,21 @@ class VirtualizeAllowCreate extends React.Component {
 
 // virtualize allowCreate + renderCreateItem, optionList render not as expected
 export const Fix1856 = () => (<VirtualizeAllowCreate />); 
+
+
+export const TestOptionKey = () => {
+  return <><Select style={{ width: 300 }}>
+      <Select.Option label='3' value='2' key='abc'></Select.Option>
+      <Select.Option label='2' value='3' key='efg'></Select.Option>
+      <Select.Option label='4' value='5'></Select.Option>
+      <Select.Option label='5' value='4'></Select.Option>
+    </Select>
+    <br/><br/>
+    <Select style={{ width: 300 }} optionList={[
+      { label: '1', value: '2', key: 'kkk' },
+      { label: '2', value: '3', key: 'jjj' },
+      { label: '3', value: '2' },
+    ]}>
+    </Select>
+  </>
+}

+ 9 - 9
packages/semi-ui/select/index.tsx

@@ -181,14 +181,14 @@ export type SelectProps = {
     showRestTagsPopover?: boolean;
     restTagsPopoverProps?: PopoverProps
 } & Pick<
-    TooltipProps,
-    | 'spacing'
-    | 'getPopupContainer'
-    | 'motion'
-    | 'autoAdjustOverflow'
-    | 'mouseLeaveDelay'
-    | 'mouseEnterDelay'
-    | 'stopPropagation'
+TooltipProps,
+| 'spacing'
+| 'getPopupContainer'
+| 'motion'
+| 'autoAdjustOverflow'
+| 'mouseLeaveDelay'
+| 'mouseEnterDelay'
+| 'stopPropagation'
 > & React.RefAttributes<any>;
 
 export interface SelectState {
@@ -775,7 +775,7 @@ class Select extends BaseComponent<SelectProps, SelectState> {
                     focused={isFocused}
                     onMouseEnter={() => this.onOptionHover(optionIndex)}
                     style={optionStyle}
-                    key={option.key || option.label as string + option.value as string + optionIndex}
+                    key={option._keyInOptionList || option._keyInJsx || option.label as string + option.value as string + optionIndex}
                     renderOptionItem={renderOptionItem}
                     inputValue={inputValue}
                     semiOptionId={`${this.selectID}-option-${optionIndex}`}

+ 7 - 1
packages/semi-ui/select/utils.tsx

@@ -10,7 +10,7 @@ const generateOption = (child: React.ReactElement, parent: any, index: number):
     }
     const option = {
         value: childProps.value,
-        // Drop-down menu rendering priority label value, children, value in turn downgrade
+        // Dropdown menu rendering priority label value, children, value in turn downgrade
         label: childProps.label || childProps.children || childProps.value,
         _show: true,
         _selected: false,
@@ -18,6 +18,12 @@ const generateOption = (child: React.ReactElement, parent: any, index: number):
         ...childProps,
         _parentGroup: parent,
     };
+
+    // Props are collected from ReactNode, after React.Children.toArray
+    // no need to determine whether the key exists in child
+    // Even if the user does not explicitly declare it, React will always generate a key.
+    option._keyInJsx = child.key;
+    
     return option;
 };