Browse Source

fix: select onChangeWithObject in multiple when optinList empty and u… (#2139)

* fix: select onChangeWithObject in multiple when optinList empty and update other key in selections, render not update

* test: add e2e test for pr 2139
pointhalo 1 year ago
parent
commit
36bf2c5095

+ 10 - 0
cypress/e2e/select.spec.js

@@ -168,6 +168,16 @@ describe('Select', () => {
 
     });
 
+    it('Fixed PR-2139', () => {
+        // 1.Select multi-select turns on onChangWithObject and value is controlled
+        // 2. The current value does not exist in optionList
+        // 3. The problem that rendering is not re - executed after updating other attributes in value(such as label, or any other Key)
+        cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/select--update-other-key-not-in-list');
+        cy.get('.render-content').eq(0).should('have.text', 'AA-Label-AA-OtherProps')
+        cy.get('#change').eq(0).click();
+        cy.get('.render-content').eq(0).should('have.text', 'AA-Label-2-AA-OtherProps-2')
+
+    });
     // it('ellipsisTrigger', () => {
     //     cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/select--fix-1560');
 

+ 12 - 1
packages/semi-foundation/select/foundation.ts

@@ -298,7 +298,18 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
                     const indexInSelectedList = selectedOptionList.findIndex(option => option.value === selectedValue);
                     if (indexInSelectedList !== -1) {
                         const option = selectedOptionList[indexInSelectedList];
-                        selections.set(option.label, option);
+                        if (onChangeWithObject) {
+                            // Although the value is the same and can be found in selections, it cannot ensure that other items remain unchanged. A comparison is made.
+                            // https://github.com/DouyinFE/semi-design/pull/2139
+                            const optionCompare = { ...(propValue[i] as any) };
+                            if (isEqual(optionCompare, option)) {
+                                selections.set(option.label, option);
+                            } else {
+                                selections.set(optionCompare.label, optionCompare);
+                            }
+                        } else {
+                            selections.set(option.label, option);
+                        }
                     } else {
                         // The current value does not exist in the current optionList or the list before the change. Construct an option and update it to the selection
                         let optionNotExist = { value: selectedValue, label: selectedValue, _notExist: true };

+ 48 - 1
packages/semi-ui/select/_story/select.stories.jsx

@@ -3463,4 +3463,51 @@ export const AllCaseOfBlur = () => {
       <br />
     </div>
   )
-}
+}
+
+export const UpdateOtherKeyNotInList = () => {
+  const [v, setV] = useState([
+    {
+      label: 'AA-Label',
+      value: 'AA',
+      otherProps: 'AA-OtherProps',
+    },
+  ]);
+
+  const change = () => {
+    setV([
+      {
+        label: 'AA-Label-2',
+        value: 'AA',
+        otherProps: 'AA-OtherProps-2',
+      },
+    ])
+  }
+
+  const renderSelectedItem = (optionNode) => {
+    const { label, otherProps } = optionNode;
+    const content = (
+      <div className='render-content'>
+        {label}-{otherProps}
+      </div>
+    );
+    return {
+      isRenderInTag: false,
+      content,
+    };
+  };
+  return (
+    <>
+      <Select
+        value={v}
+        onChange={setV}
+        filter
+        multiple
+        renderSelectedItem={renderSelectedItem}
+        onChangeWithObject
+        style={{ width: 320 }}
+      />
+      <Button id='change' onClick={() => change()}>change</Button>
+    </>
+  );
+};