diff --git a/components/radio/__tests__/group.test.js b/components/radio/__tests__/group.test.js
index ace814c4d091..5aa9adad828c 100644
--- a/components/radio/__tests__/group.test.js
+++ b/components/radio/__tests__/group.test.js
@@ -170,10 +170,35 @@ describe('Radio Group', () => {
});
it('passes prefixCls down to radio', () => {
- const options = [{ label: 'Apple', value: 'Apple' }, { label: 'Orange', value: 'Orange', style: { fontSize: 12 } }];
+ const options = [
+ { label: 'Apple', value: 'Apple' },
+ { label: 'Orange', value: 'Orange', style: { fontSize: 12 } },
+ ];
const wrapper = render();
expect(wrapper).toMatchSnapshot();
});
+
+ describe('value is null or undefined', () => {
+ it('use `defaultValue` when `value` is undefined', () => {
+ const options = [{ label: 'Bamboo', value: 'bamboo' }];
+ const wrapper = mount(
+ ,
+ );
+
+ expect(wrapper.state().value).toEqual('bamboo');
+ });
+
+ [undefined, null].forEach(newValue => {
+ it(`should set value back when value change back to ${newValue}`, () => {
+ const options = [{ label: 'Bamboo', value: 'bamboo' }];
+ const wrapper = mount();
+ expect(wrapper.state().value).toEqual('bamboo');
+
+ wrapper.setProps({ value: newValue });
+ expect(wrapper.state().value).toEqual(newValue);
+ });
+ });
+ });
});
diff --git a/components/radio/group.tsx b/components/radio/group.tsx
index aec896ab798f..3eca00110013 100644
--- a/components/radio/group.tsx
+++ b/components/radio/group.tsx
@@ -28,28 +28,29 @@ class RadioGroup extends React.PureComponent {
buttonStyle: 'outline' as RadioGroupButtonStyle,
};
- static getDerivedStateFromProps(nextProps: RadioGroupProps) {
- if ('value' in nextProps) {
- return {
- value: nextProps.value,
- };
- }
- const checkedValue = getCheckedValue(nextProps.children);
- if (checkedValue) {
- return {
- value: checkedValue.value,
- };
+ static getDerivedStateFromProps(nextProps: RadioGroupProps, prevState: RadioGroupState) {
+ const newState: Partial = {
+ prevPropValue: nextProps.value,
+ };
+
+ if (nextProps.value !== undefined || prevState.prevPropValue !== nextProps.value) {
+ newState.value = nextProps.value;
+ } else {
+ const checkedValue = getCheckedValue(nextProps.children);
+ if (checkedValue) {
+ newState.value = checkedValue.value;
+ }
}
- return null;
+ return newState;
}
constructor(props: RadioGroupProps) {
super(props);
let value;
- if ('value' in props) {
+ if (props.value !== undefined) {
value = props.value;
- } else if ('defaultValue' in props) {
+ } else if (props.defaultValue !== undefined) {
value = props.defaultValue;
} else {
const checkedValue = getCheckedValue(props.children);
@@ -57,6 +58,7 @@ class RadioGroup extends React.PureComponent {
}
this.state = {
value,
+ prevPropValue: props.value,
};
}
diff --git a/components/radio/interface.tsx b/components/radio/interface.tsx
index 528f82820f79..8767046b9b55 100644
--- a/components/radio/interface.tsx
+++ b/components/radio/interface.tsx
@@ -20,6 +20,7 @@ export interface RadioGroupProps extends AbstractCheckboxGroupProps {
export interface RadioGroupState {
value: any;
+ prevPropValue: any;
}
export interface RadioGroupContextProps {