Browse Source

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

* test driven

* adjust raido group logic
pull/22247/head
二货机器人 5 years ago
committed by GitHub
parent
commit
c86c3cf5a1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 27
      components/radio/__tests__/group.test.js
  2. 30
      components/radio/group.tsx
  3. 1
      components/radio/interface.tsx

27
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(<RadioGroup prefixCls="my-radio" options={options} />);
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);
});
});
});
});

30
components/radio/group.tsx

@ -28,28 +28,29 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
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<RadioGroupState> = {
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<RadioGroupProps, RadioGroupState> {
}
this.state = {
value,
prevPropValue: props.value,
};
}

1
components/radio/interface.tsx

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

Loading…
Cancel
Save