繁体   English   中英

如何避免使用 React-Navigation 的组件重复?

[英]How to avoid duplication of components using React-Navigation?

我有5 个屏幕具有相同的 styles 和布局,但一些文本和按钮逻辑不同。

我试图将所有内容都保存在一个组件中,并在那里传递我需要模仿的组件的名称,但它在嵌套的 if/else中长大,这使得代码非常复杂。

这两个弊端中哪一个更小,我应该怎么做:为了简单而复制组件,或者将它们放在一个地方并失去可读性?

这是“一体式”组件

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>

答案是你不应该耦合属于不同用例的组件,因为它们会因不同的原因在不同的时间发生变化,即使它们现在看起来相同,以后也会发生变化。 不要写覆盖所有用例的“超级组件”,因为它很快就会变得一团糟

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM