Skip to content

Commit ca555b5

Browse files
committed
refactor(Radio): 使用Function组件重构 Class组件
1 parent 03a2d49 commit ca555b5

File tree

1 file changed

+66
-84
lines changed

1 file changed

+66
-84
lines changed

packages/core/src/Radio/index.tsx

Lines changed: 66 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Component } from 'react';
1+
import React, { Component, useEffect, useState } from 'react';
22
import {
33
View,
44
ViewProps,
@@ -60,104 +60,86 @@ export interface RadioState {
6060
control: 'state' | 'props';
6161
}
6262

63-
export default class Radio extends Component<RadioProps, RadioState> {
64-
static defaultProps: RadioProps = {
65-
checked: false,
66-
circleSize: 20,
67-
checkedColor: '#008EF0',
68-
borderColor: '#bdc1cc',
69-
color: '#c3c5c7',
70-
thumbSize: 12,
71-
};
72-
constructor(props: RadioProps) {
73-
super(props);
74-
this.state = {
75-
checked: props.checked,
76-
sizeValue: new Animated.Value(0),
77-
control: 'state',
78-
};
79-
}
80-
componentDidMount() {
81-
this.animatedStart(this.props.checked);
82-
}
83-
static getDerivedStateFromProps(props: RadioProps, state: RadioState) {
63+
export default function Radio(props: RadioProps) {
64+
const [state, setState] = useState({
65+
checked: props.checked,
66+
sizeValue: new Animated.Value(0),
67+
control: 'state',
68+
});
69+
70+
useEffect(() => {
71+
animatedStart(props.checked);
72+
}, []);
73+
74+
useEffect(() => {
8475
if (state.control === 'state' && props.checked === state.checked) {
85-
return {
86-
control: 'props',
87-
};
76+
return setState({ ...state, control: 'props' });
8877
}
8978
if (props.checked !== state.checked) {
9079
Animated.spring(state.sizeValue, {
9180
toValue: !!props.checked ? props.thumbSize! : 0,
9281
overshootClamping: true,
9382
useNativeDriver: false,
9483
}).start();
95-
return {
96-
checked: props.checked,
97-
control: 'props',
98-
};
84+
return setState({ ...state, checked: props.checked, control: 'props' });
9985
}
100-
return null;
101-
}
102-
animatedStart(checked?: boolean) {
103-
Animated.spring(this.state.sizeValue, {
104-
toValue: !!checked ? this.props.thumbSize! : 0,
86+
}, [props.checked]);
87+
88+
function animatedStart(checked?: boolean) {
89+
Animated.spring(state.sizeValue, {
90+
toValue: !!checked ? props.thumbSize! : 0,
10591
overshootClamping: true,
10692
useNativeDriver: false,
10793
}).start();
10894
}
109-
handlePress = (event: GestureResponderEvent) => {
110-
const { onPress } = this.props;
111-
this.setState({ checked: true, control: 'state' }, () => {
112-
this.animatedStart(true);
113-
onPress && onPress(event);
114-
});
95+
96+
const handlePress = (event: GestureResponderEvent) => {
97+
const { onPress } = props;
98+
setState({ ...state, checked: true, control: 'state' });
99+
100+
animatedStart(true);
101+
onPress && onPress(event);
115102
};
116-
render() {
117-
const {
118-
style,
119-
color,
120-
circleSize,
121-
thumbSize,
122-
disabled,
123-
checkedColor,
124-
borderColor: bdColor,
125-
...otherProps
126-
} = this.props;
127-
const sizeValue = this.state.sizeValue.interpolate({
128-
inputRange: [0, thumbSize!],
129-
outputRange: [0, thumbSize!],
130-
// extrapolate: 'clamp',
131-
});
132-
const backgroundColor = disabled ? color : checkedColor;
133-
const borderColor = disabled ? color : bdColor;
134-
return (
135-
<View testID="RNE__Radio__wrap" style={[styles.defalut, style]} {...otherProps}>
136-
<TouchableOpacity
137-
disabled={disabled}
138-
style={[styles.touch]}
139-
onPress={this.handlePress}
140-
testID="RNE__Radio__view"
103+
104+
const { style, color, circleSize, thumbSize, disabled, checkedColor, borderColor: bdColor, ...otherProps } = props;
105+
const sizeValue = state.sizeValue.interpolate({
106+
inputRange: [0, thumbSize!],
107+
outputRange: [0, thumbSize!],
108+
// extrapolate: 'clamp',
109+
});
110+
const backgroundColor = disabled ? color : checkedColor;
111+
const borderColor = disabled ? color : bdColor;
112+
113+
return (
114+
<View testID="RNE__Radio__wrap" style={[styles.defalut, style]} {...otherProps}>
115+
<TouchableOpacity disabled={disabled} style={[styles.touch]} onPress={handlePress} testID="RNE__Radio__view">
116+
<Animated.View
117+
style={[styles.checkBg, { width: circleSize, height: circleSize, borderColor }]}
118+
testID="RNE__Radio__border"
141119
>
142120
<Animated.View
143-
style={[styles.checkBg, { width: circleSize, height: circleSize, borderColor }]}
144-
testID="RNE__Radio__border"
121+
style={[styles.check, { width: sizeValue, height: sizeValue, backgroundColor }]}
122+
testID="RNE__Radio__box"
123+
/>
124+
</Animated.View>
125+
{props.children && (
126+
<MaybeTextOrView
127+
// eslint-disable-next-line
128+
style={[styles.label, { opacity: disabled ? 0.3 : 1 }]}
145129
>
146-
<Animated.View
147-
style={[styles.check, { width: sizeValue, height: sizeValue, backgroundColor }]}
148-
testID="RNE__Radio__box"
149-
/>
150-
</Animated.View>
151-
{this.props.children && (
152-
<MaybeTextOrView
153-
// eslint-disable-next-line
154-
style={[styles.label, { opacity: disabled ? 0.3 : 1 }]}
155-
>
156-
{this.props.children}
157-
</MaybeTextOrView>
158-
)}
159-
</TouchableOpacity>
160-
</View>
161-
);
162-
}
130+
{props.children}
131+
</MaybeTextOrView>
132+
)}
133+
</TouchableOpacity>
134+
</View>
135+
);
163136
}
137+
138+
Radio.defaultProps = {
139+
checked: false,
140+
circleSize: 20,
141+
checkedColor: '#008EF0',
142+
borderColor: '#bdc1cc',
143+
color: '#c3c5c7',
144+
thumbSize: 12,
145+
} as RadioProps;

0 commit comments

Comments
 (0)