fix: #21134 checkbox can't receive context update from checkbox group (#21146)

* fix checkbox can't receive context update issue

* add test case for checkbox handling context update
This commit is contained in:
Teng YANG 2020-01-31 21:25:34 +08:00 committed by GitHub
parent db99fe752f
commit 048a6e28a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 25 deletions

View File

@ -1,9 +1,8 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import classNames from 'classnames';
import RcCheckbox from 'rc-checkbox';
import shallowEqual from 'shallowequal';
import CheckboxGroup, { CheckboxGroupContext } from './Group';
import CheckboxGroup, { CheckboxGroupContext, GroupContext } from './Group';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
@ -52,9 +51,7 @@ class Checkbox extends React.Component<CheckboxProps, {}> {
indeterminate: false,
};
static contextTypes = {
checkboxGroup: PropTypes.any,
};
static contextType = GroupContext;
context: any;

View File

@ -43,6 +43,10 @@ export interface CheckboxGroupContext {
};
}
export const GroupContext = React.createContext<{ checkboxGroup: any }>({
checkboxGroup: undefined,
});
class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupState> {
static defaultProps = {
options: [],
@ -55,10 +59,6 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
onChange: PropTypes.func,
};
static childContextTypes = {
checkboxGroup: PropTypes.any,
};
static getDerivedStateFromProps(nextProps: CheckboxGroupProps) {
if ('value' in nextProps) {
return {
@ -76,21 +76,6 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
};
}
getChildContext() {
return {
checkboxGroup: {
toggleOption: this.toggleOption,
value: this.state.value,
disabled: this.props.disabled,
name: this.props.name,
// https://github.com/ant-design/ant-design/issues/16376
registerValue: this.registerValue,
cancelValue: this.cancelValue,
},
};
}
shouldComponentUpdate(nextProps: CheckboxGroupProps, nextState: CheckboxGroupState) {
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
}
@ -173,10 +158,23 @@ class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupSta
));
}
const context = {
checkboxGroup: {
toggleOption: this.toggleOption,
value: this.state.value,
disabled: this.props.disabled,
name: this.props.name,
// https://github.com/ant-design/ant-design/issues/16376
registerValue: this.registerValue,
cancelValue: this.cancelValue,
},
};
const classString = classNames(groupPrefixCls, className);
return (
<div className={classString} style={style} {...domProps}>
{children}
<GroupContext.Provider value={context}>{children}</GroupContext.Provider>
</div>
);
};

View File

@ -1,5 +1,6 @@
import React from 'react';
import { mount, render } from 'enzyme';
import Collapse from '../../collapse';
import Checkbox from '../index';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -181,4 +182,44 @@ describe('CheckboxGroup', () => {
.simulate('change');
expect(onChange).toHaveBeenCalledWith([1, 2]);
});
// https://github.com/ant-design/ant-design/issues/21134
it('should work when checkbox is wrapped by other components', () => {
const wrapper = mount(
<Checkbox.Group>
<Collapse bordered={false}>
<Collapse.Panel header="test panel">
<div>
<Checkbox value="1">item</Checkbox>
</div>
</Collapse.Panel>
</Collapse>
</Checkbox.Group>,
);
wrapper
.find('.ant-collapse-item')
.at(0)
.find('.ant-collapse-header')
.simulate('click');
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
expect(
wrapper
.find(Checkbox.Group)
.at(0)
.state('value'),
).toEqual(['1']);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
expect(
wrapper
.find(Checkbox.Group)
.at(0)
.state('value'),
).toEqual([]);
});
});