mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 09:26:06 +08:00
chore: replace legacy context and use PureComponent (#21597)
This commit is contained in:
parent
0f5dc22966
commit
e3fbb0dbd4
8
components/radio/context.tsx
Normal file
8
components/radio/context.tsx
Normal file
@ -0,0 +1,8 @@
|
||||
import * as React from 'react';
|
||||
import { RadioGroupContextProps } from './interface';
|
||||
|
||||
const RadioGroupContext = React.createContext<RadioGroupContextProps | null>(null);
|
||||
|
||||
export const RadioGroupContextProvider = RadioGroupContext.Provider;
|
||||
|
||||
export default RadioGroupContext;
|
@ -1,5 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import Radio from './radio';
|
||||
import {
|
||||
@ -10,6 +9,7 @@ import {
|
||||
} from './interface';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import SizeContext from '../config-provider/SizeContext';
|
||||
import { RadioGroupContextProvider } from './context';
|
||||
|
||||
function getCheckedValue(children: React.ReactNode) {
|
||||
let value = null;
|
||||
@ -28,10 +28,6 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
|
||||
buttonStyle: 'outline' as RadioGroupButtonStyle,
|
||||
};
|
||||
|
||||
static childContextTypes = {
|
||||
radioGroup: PropTypes.any,
|
||||
};
|
||||
|
||||
static getDerivedStateFromProps(nextProps: RadioGroupProps) {
|
||||
if ('value' in nextProps) {
|
||||
return {
|
||||
@ -64,17 +60,6 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
|
||||
};
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
radioGroup: {
|
||||
onChange: this.onRadioChange,
|
||||
value: this.state.value,
|
||||
disabled: this.props.disabled,
|
||||
name: this.props.name,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
onRadioChange = (ev: RadioChangeEvent) => {
|
||||
const lastValue = this.state.value;
|
||||
const { value } = ev.target;
|
||||
@ -167,7 +152,18 @@ class RadioGroup extends React.PureComponent<RadioGroupProps, RadioGroupState> {
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ConfigConsumer>{this.renderGroup}</ConfigConsumer>;
|
||||
return (
|
||||
<RadioGroupContextProvider
|
||||
value={{
|
||||
onChange: this.onRadioChange,
|
||||
value: this.state.value,
|
||||
disabled: this.props.disabled,
|
||||
name: this.props.name,
|
||||
}}
|
||||
>
|
||||
<ConfigConsumer>{this.renderGroup}</ConfigConsumer>
|
||||
</RadioGroupContextProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ Radio.
|
||||
|
||||
## API
|
||||
|
||||
### Radio
|
||||
### Radio/Radio.Button
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
|
@ -14,13 +14,14 @@ title: Radio
|
||||
|
||||
## API
|
||||
|
||||
### Radio
|
||||
### Radio/Radio.Button
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| -------------- | --------------------------------- | ------- | ------ |
|
||||
| autoFocus | 自动获取焦点 | boolean | false |
|
||||
| checked | 指定当前是否选中 | boolean | false |
|
||||
| defaultChecked | 初始是否选中 | boolean | false |
|
||||
| disabled | 禁用 Radio | boolean | false |
|
||||
| value | 根据 value 进行比较,判断是否选中 | any | |
|
||||
|
||||
### RadioGroup
|
||||
|
@ -22,13 +22,11 @@ export interface RadioGroupState {
|
||||
value: any;
|
||||
}
|
||||
|
||||
export interface RadioGroupContext {
|
||||
radioGroup: {
|
||||
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||
value: any;
|
||||
disabled: boolean;
|
||||
name: string;
|
||||
};
|
||||
export interface RadioGroupContextProps {
|
||||
onChange: (e: RadioChangeEvent) => void;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export type RadioProps = AbstractCheckboxProps<RadioChangeEvent>;
|
||||
|
@ -1,14 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import RcCheckbox from 'rc-checkbox';
|
||||
import classNames from 'classnames';
|
||||
import shallowEqual from 'shallowequal';
|
||||
import RadioGroup from './group';
|
||||
import RadioButton from './radioButton';
|
||||
import { RadioProps, RadioChangeEvent, RadioGroupContext } from './interface';
|
||||
import { RadioProps, RadioChangeEvent } from './interface';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import RadioGroupContext from './context';
|
||||
|
||||
export default class Radio extends React.Component<RadioProps, {}> {
|
||||
export default class Radio extends React.PureComponent<RadioProps, {}> {
|
||||
static Group: typeof RadioGroup;
|
||||
|
||||
static Button: typeof RadioButton;
|
||||
@ -17,22 +16,10 @@ export default class Radio extends React.Component<RadioProps, {}> {
|
||||
type: 'radio',
|
||||
};
|
||||
|
||||
static contextTypes = {
|
||||
radioGroup: PropTypes.any,
|
||||
};
|
||||
|
||||
context: any;
|
||||
static contextType = RadioGroupContext;
|
||||
|
||||
private rcCheckbox: any;
|
||||
|
||||
shouldComponentUpdate(nextProps: RadioProps, nextState: {}, nextContext: RadioGroupContext) {
|
||||
return (
|
||||
!shallowEqual(this.props, nextProps) ||
|
||||
!shallowEqual(this.state, nextState) ||
|
||||
!shallowEqual(this.context.radioGroup, nextContext.radioGroup)
|
||||
);
|
||||
}
|
||||
|
||||
saveCheckbox = (node: any) => {
|
||||
this.rcCheckbox = node;
|
||||
};
|
||||
@ -42,8 +29,8 @@ export default class Radio extends React.Component<RadioProps, {}> {
|
||||
this.props.onChange(e);
|
||||
}
|
||||
|
||||
if (this.context.radioGroup && this.context.radioGroup.onChange) {
|
||||
this.context.radioGroup.onChange(e);
|
||||
if (this.context?.onChange) {
|
||||
this.context.onChange(e);
|
||||
}
|
||||
};
|
||||
|
||||
@ -58,14 +45,13 @@ export default class Radio extends React.Component<RadioProps, {}> {
|
||||
renderRadio = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
|
||||
const { props, context } = this;
|
||||
const { prefixCls: customizePrefixCls, className, children, style, ...restProps } = props;
|
||||
const { radioGroup } = context;
|
||||
const prefixCls = getPrefixCls('radio', customizePrefixCls);
|
||||
const radioProps: RadioProps = { ...restProps };
|
||||
if (radioGroup) {
|
||||
radioProps.name = radioGroup.name;
|
||||
if (context) {
|
||||
radioProps.name = context.name;
|
||||
radioProps.onChange = this.onChange;
|
||||
radioProps.checked = props.value === radioGroup.value;
|
||||
radioProps.disabled = props.disabled || radioGroup.disabled;
|
||||
radioProps.checked = props.value === context.value;
|
||||
radioProps.disabled = props.disabled || context.disabled;
|
||||
}
|
||||
const wrapperClassString = classNames(className, {
|
||||
[`${prefixCls}-wrapper`]: true,
|
||||
|
@ -1,31 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import * as PropTypes from 'prop-types';
|
||||
import Radio from './radio';
|
||||
import { RadioChangeEvent } from './interface';
|
||||
import { AbstractCheckboxProps } from '../checkbox/Checkbox';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import RadioGroupContext from './context';
|
||||
|
||||
export type RadioButtonProps = AbstractCheckboxProps<RadioChangeEvent>;
|
||||
|
||||
export default class RadioButton extends React.Component<RadioButtonProps, any> {
|
||||
static contextTypes = {
|
||||
radioGroup: PropTypes.any,
|
||||
};
|
||||
const RadioButton = (props: RadioButtonProps) => {
|
||||
const radioGroupContext = React.useContext(RadioGroupContext);
|
||||
|
||||
context: any;
|
||||
return (
|
||||
<ConfigConsumer>
|
||||
{({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { prefixCls: customizePrefixCls, ...radioProps }: RadioButtonProps = props;
|
||||
const prefixCls = getPrefixCls('radio-button', customizePrefixCls);
|
||||
if (radioGroupContext) {
|
||||
radioProps.checked = props.value === radioGroupContext.value;
|
||||
radioProps.disabled = props.disabled || radioGroupContext.disabled;
|
||||
}
|
||||
return <Radio prefixCls={prefixCls} {...radioProps} />;
|
||||
}}
|
||||
</ConfigConsumer>
|
||||
);
|
||||
};
|
||||
|
||||
renderRadioButton = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
const { prefixCls: customizePrefixCls, ...radioProps }: RadioButtonProps = this.props;
|
||||
const prefixCls = getPrefixCls('radio-button', customizePrefixCls);
|
||||
if (this.context.radioGroup) {
|
||||
radioProps.checked = this.props.value === this.context.radioGroup.value;
|
||||
radioProps.disabled = this.props.disabled || this.context.radioGroup.disabled;
|
||||
}
|
||||
|
||||
return <Radio prefixCls={prefixCls} {...radioProps} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <ConfigConsumer>{this.renderRadioButton}</ConfigConsumer>;
|
||||
}
|
||||
}
|
||||
export default RadioButton;
|
||||
|
Loading…
Reference in New Issue
Block a user