如何避免在React中复制组件?

问题描述 投票:0回答:1

我有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)
javascript reactjs react-native react-navigation
1个回答
2
投票

[使一个通用按钮组件将一个单击处理程序和文本作为道具,然后将值作为道具传递:

例如,如果您有一些按钮组件,例如:

export const Button = ({ children, handler }) =>
  <button onPress={handler}>
    {children}
  </button>;

然后您可以像使用它一样>>

<Button handler={this.yourClickHandler} >{"Some Text"}</Button>
© www.soinside.com 2019 - 2024. All rights reserved.