Browse Source

Fix: when radio-group's value is NaN, "Maimum update depth exceeded" is triggered (#716)

* fix(radio): when radio-group's value is NaN, triggers Maximum call stack

* test(radio): added tests for radio-group when value is NaN

* fix(radio): only checks if prevProps.value is NaN

* fix(radio): short-circuit when prev and this.prop are NaN
Chenxiao Guan 3 years ago
parent
commit
d191df04f3

+ 9 - 1
packages/semi-ui/radio/__test__/radioGroup.test.jsx

@@ -196,4 +196,12 @@ describe('RadioGroup', () => {
         expect(middleRadio.exists(`.${BASE_CLASS_PREFIX}-radio-addon-buttonRadio-middle`)).toEqual(true);
         expect(largeRadio.exists(`.${BASE_CLASS_PREFIX}-radio-addon-buttonRadio-large`)).toEqual(true);
     });
-});
+
+    it('does not trigger Maximum update exceeded when setting radio-group\'s value to NaN', () => {
+        const radioGroup = mount(
+            createRadioGroup({ value: NaN }),
+        );
+
+        expect(radioGroup.exists(`${BASE_CLASS_PREFIX}-radio-checked`)).toEqual(false);
+    });
+});

+ 9 - 0
packages/semi-ui/radio/radioGroup.tsx

@@ -97,6 +97,15 @@ class RadioGroup extends BaseComponent<RadioGroupProps, RadioGroupState> {
     }
 
     componentDidUpdate(prevProps: RadioGroupProps) {
+        if (typeof prevProps.value === 'number'
+            && isNaN(prevProps.value)
+            && typeof this.props.value === 'number'
+            && isNaN(this.props.value)
+        ) {
+            // `NaN === NaN` returns false, and this will fail the next if check
+            // therefore triggering an infinite loop
+            return;
+        }
         if (prevProps.value !== this.props.value) {
             this.foundation.handlePropValueChange(this.props.value);
         }