refactor: Adjust Radio.Group logic that value is undefined should be uncontrolled mode. (#22245)

* test driven

* adjust raido group logic
This commit is contained in:
二货机器人 2020-03-16 12:47:24 +08:00 committed by GitHub
parent bb1da55a55
commit c86c3cf5a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 15 deletions

View File

@ -170,10 +170,35 @@ describe('Radio Group', () => {
}); });
it('passes prefixCls down to radio', () => { 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(<RadioGroup prefixCls="my-radio" options={options} />); const wrapper = render(<RadioGroup prefixCls="my-radio" options={options} />);
expect(wrapper).toMatchSnapshot(); 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(
<RadioGroup defaultValue="bamboo" value={undefined} options={options} />,
);
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(<RadioGroup value="bamboo" options={options} />);
expect(wrapper.state().value).toEqual('bamboo');
wrapper.setProps({ value: newValue });
expect(wrapper.state().value).toEqual(newValue);
});
});
});
}); });

View File

@ -28,28 +28,29 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
buttonStyle: 'outline' as RadioGroupButtonStyle, buttonStyle: 'outline' as RadioGroupButtonStyle,
}; };
static getDerivedStateFromProps(nextProps: RadioGroupProps) { static getDerivedStateFromProps(nextProps: RadioGroupProps, prevState: RadioGroupState) {
if ('value' in nextProps) { const newState: Partial<RadioGroupState> = {
return { prevPropValue: nextProps.value,
value: nextProps.value,
}; };
}
if (nextProps.value !== undefined || prevState.prevPropValue !== nextProps.value) {
newState.value = nextProps.value;
} else {
const checkedValue = getCheckedValue(nextProps.children); const checkedValue = getCheckedValue(nextProps.children);
if (checkedValue) { if (checkedValue) {
return { newState.value = checkedValue.value;
value: checkedValue.value, }
};
} }
return null; return newState;
} }
constructor(props: RadioGroupProps) { constructor(props: RadioGroupProps) {
super(props); super(props);
let value; let value;
if ('value' in props) { if (props.value !== undefined) {
value = props.value; value = props.value;
} else if ('defaultValue' in props) { } else if (props.defaultValue !== undefined) {
value = props.defaultValue; value = props.defaultValue;
} else { } else {
const checkedValue = getCheckedValue(props.children); const checkedValue = getCheckedValue(props.children);
@ -57,6 +58,7 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
} }
this.state = { this.state = {
value, value,
prevPropValue: props.value,
}; };
} }

View File

@ -20,6 +20,7 @@ export interface RadioGroupProps extends AbstractCheckboxGroupProps {
export interface RadioGroupState { export interface RadioGroupState {
value: any; value: any;
prevPropValue: any;
} }
export interface RadioGroupContextProps { export interface RadioGroupContextProps {