我有5个屏幕,它们的样式和布局相同,但是文本和按钮的逻辑有所不同。我试图将所有内容保留在one component中,并在其中传递我需要模仿的组件的名称,但是它在nested if / else周围长大,这使代码变得非常复杂。这两个弊端中较小的是什么,我该怎么做:duplicate组件的代码偏向于简单,或者将它们保留在one place中并失去可读性?
这里是“多合一”组件
const Pin = props => {
const {
navigation: { navigate, getParam },
loading,
savePin,
signIn,
toggleModal,
} = props
const [pin, setPin] = useState('')
const isInSignInStack = getParam('isInSignInStack') ? 'isInSignInStack' : false
const isConfirmPinSignUp = getParam('isConfirmPinSignUp') ? 'isConfirmPinSignUp' : false
const isChangePin = getParam('isChangePin') ? 'isChangePin' : false
const isEnterNewPin = getParam('isEnterNewPin') ? 'isEnterNewPin' : false
const isConfirmNewPin = getParam('isConfirmNewPin') ? 'isConfirmNewPin' : false
const newPin = getParam('newPin')
const handleSavePin = () => savePin(pin).then(() => navigate('ConfirmPinSignUp'))
const navigateHome = () => navigate('Home')
const handleAuthenticate = () =>
compose(
then(navigateHome),
then(signIn),
savePin
)(pin)
const validatePin = () =>
isConfirmNewPin
? equals(newPin, pin)
? savePin(pin).then(() => navigate('SuccessPinChange'))
: toggleModal('pin isn't match')
: getPin().then(({ password }) =>
equals(password, pin)
? navigate(isChangePin ? 'ConfirmNewPin' : 'Success', { ...(isChangePin ? { newPin: pin } : {}) })
: toggleModal('pin isn't match')
)
const textObj = {
isInSignInStack: 'Enter your pin',
isConfirmPinSignUp: 'Enter your pin once again',
isChangePin: 'Enter your old pin',
isEnterNewPin: 'Enter the new pin',
isConfirmNewPin: 'Enter the new pin once again',
}
return (
<Container style={styles.container}>
<Content scrollEnabled={false} contentContainerStyle={styles.content}>
<Text style={styles.headerText}>
{pathOr(
'Come up with the new pin',
isInSignInStack || isConfirmPinSignUp || isChangePin || isEnterNewPin || isConfirmNewPin,
textObj
)}
</Text>
<View style={styles.inputView}>
<CodeInput />
</View>
{isConfirmPinSignUp || (
<View style={styles.aknowledgementView}>
{isInSignInStack
? <Text style={styles.text} onPress={handleForgotPassword}>
FORGOT PIN
</Text>
: isEnterNewPin && (
<>
<Text style={styles.greenText}>Attention! Don't use your old pin</Text>
<Text style={styles.greenText}>codes or passwords, come up with the new one</Text>
</>
)}
</View>
)}
<Button
style={isEmpty(pin) ? styles.btnDisabled : styles.btn}
onPress={() =>
isInSignInStack
? handleAuthenticate
: anyTrue(isConfirmPinSignUp, isChangePin) ? validatePin : handleSavePin
}
disabled={anyTrue(isEmpty(pin), loading)}
>
{loading ? <Spinner color="black" /> : <Text style={styles.btnText}>Next</Text>}
</Button>
</Content>
</Container>
)
}
Pin.navigationOptions = ({ navigation: { getParam } }) => {
const isInSignInStack = getParam('isInSignInStack')
const isChangePin = getParam('isChangePin')
const isEnterNewPin = getParam('isEnterNewPin')
return {
title: isInSignInStack ? 'SignIn' : anyTrue(isChangePin, isEnterNewPin) ? 'Change PIN' : 'Register'
}
}
const styles = StyleSheet.create({
//
})
Pin.propTypes = {
navigation: PropTypes.shape({
navigate: PropTypes.func,
getParam: PropTypes.func,
}).isRequired,
loading: PropTypes.bool.isRequired,
savePin: PropTypes.func.isRequired,
toggleModal: PropTypes.func.isRequired,
signIn: PropTypes.func.isRequired,
}
const mapStateToProps = compose(
pick(['loading']),
path(['user'])
)
const mapDispatchToProps = {
savePin,
signIn,
toggleModal,
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Pin)
[使一个通用按钮组件将一个单击处理程序和文本作为道具,然后将值作为道具传递:
例如,如果您有一些按钮组件,例如:
export const Button = ({ children, handler }) =>
<button onPress={handler}>
{children}
</button>;
然后您可以像使用它一样>>
<Button handler={this.yourClickHandler} >{"Some Text"}</Button>