fix: callback is triggered only when the value changes (#4278)

* callback is triggered only when the value changes

* optimize lastValue assignment
This commit is contained in:
Rex 2016-12-19 10:52:47 +08:00 committed by Benjy Cui
parent e1d73eb424
commit ca8e88971a
2 changed files with 59 additions and 3 deletions

View File

@ -1,9 +1,21 @@
import React from 'react';
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import Radio from '../radio';
import RadioGroup from '../group';
describe('Radio', () => {
function createRadioGroup(props) {
return (
<RadioGroup
{...props}
>
<Radio value="A">A</Radio>
<Radio value="B">B</Radio>
<Radio value="C">C</Radio>
</RadioGroup>
);
}
it('responses hover events', () => {
const onMouseEnter = jest.fn();
const onMouseLeave = jest.fn();
@ -23,4 +35,46 @@ describe('Radio', () => {
wrapper.simulate('mouseleave');
expect(onMouseLeave).toHaveBeenCalled();
});
it('fire change events when value changes', () => {
const onChange = jest.fn();
const wrapper = mount(
createRadioGroup({
onChange
})
);
const radios = wrapper.find('input');
// uncontrolled component
wrapper.setState({ value: 'B' });
radios.at(0).simulate('change');
expect(onChange.mock.calls.length).toBe(1);
// controlled component
wrapper.setProps({ value: 'A' });
radios.at(1).simulate('change');
expect(onChange.mock.calls.length).toBe(2);
});
it('won\'t fire change events when value not changes', () => {
const onChange = jest.fn();
const wrapper = mount(
createRadioGroup({
onChange
})
);
const radios = wrapper.find('input');
// uncontrolled component
wrapper.setState({ value: 'B' });
radios.at(1).simulate('change');
expect(onChange.mock.calls.length).toBe(0);
// controlled component
wrapper.setProps({ value: 'A' });
radios.at(0).simulate('change');
expect(onChange.mock.calls.length).toBe(0);
});
});

View File

@ -71,14 +71,16 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
}
onRadioChange = (ev) => {
const lastValue = this.state.value;
const { value } = ev.target;
if (!('value' in this.props)) {
this.setState({
value: ev.target.value,
value,
});
}
const onChange = this.props.onChange;
if (onChange) {
if (onChange && value !== lastValue) {
onChange(ev);
}
}