React Native:如何使用/使用 <TextInput/> 使格式卡过期?

Posted

技术标签:

【中文标题】React Native:如何使用/使用 <TextInput/> 使格式卡过期?【英文标题】:React Native: How to make format card expiration with / using <TextInput/>? 【发布时间】:2017-03-11 20:36:34 【问题描述】:

在使用&lt;TextInput/&gt; 的React Native 中,我试图让/ 仅在&lt;TextInput/&gt; 被聚焦时出现,并且如果输入另一个输入,它将保持在那里。目前,格式是MM/YY,所以当用户输入第三个数字时,它会在/之后,如果用户按下回,它将删除/之前的数字。

那么,前面提到的正确实施方法是什么?谢谢你,一定会接受答案。

我尝试了以下方法,但出现长度错误,这只是在输入两位数后添加/

  _changeCardExpiry(value) 
    if (value.indexOf('.') >= 0 || value.length > 5) 
      return;
    

    if (value.length === 2 && this.state.cardExpiry.length === 1) 
      value += '/'
    

    //then update state cardExpiry
  

  ...

  <TextInput
    onChangeText=this._changeCardExpiry.bind(this)
    placeholder='MM/YY'
    value=cardExpiry
  />

【问题讨论】:

长度有什么错误? @PaulBGD 我在if (text.length === 2 &amp;&amp; this.state.cardExpiry.length === 1) 收到错误消息Cannot read property 'length' of undefined. 【参考方案1】:

您可以在一个上使用 2 个 TextInputs 来保持简单。

这是一种方法。

<TextInput
            onChangeText=() => alert('update state with Expiry Month')
            placeholder="MM/"
            value=expiryMonth
          />
          expiryMonth.length > 0 && <Text> / </Text>
          <TextInput
            onChangeText=() => alert('update state with Expiry Year or do whatever you need with whole Expiry Date')
            placeholder="YY"
            value=expiryYear
          />

【讨论】:

【参考方案2】:

你可以在 onChangeText 中使用这个函数;

别忘了在构造函数中绑定方法;

this.fixCardText = this.fixCardText.bind(this)

fixCardText(text)
  if(text.length == 2 && this.state.text.length == 1)
    text += '/'
  else if(text.length == 2 && this.state.text.length == 3)
    text = text.substring(0 , text.length-1)
  
  this.setState(text:text) 

您的文本输入应该是这样的;

<TextInput
  value = this.state.text
  onChangeText=(text)=>this.fixCardText(text)
/>

【讨论】:

【参考方案3】:

不完整的解决方案,但它解决了类似的问题 - 屏蔽蓝牙地址ABAB:CAB:CD:EF:GH:IJ:KL

/*
Usage:
import  TextInput  from '../utils/input'
const MaskedTextInput = withMask(TextInput)
<MaskedTextInput
  placeholder="Printer address"
  value= printerId 
  onChange=this.handlePrinterAddressChange
/>
*/

import React,  Component  from 'react'
import  View  from 'react-native'

export const withMask = (WrappedComponent) => class Wrapper extends Component 

  constructor(props) 
    super()
    this.state =  value: props.value 
  

  onChange(event) 
    let value = event.nativeEvent.text
    const rawValue = event.nativeEvent.text.replace(/:/g, '')

    if (rawValue) 
      value = rawValue.match(/.1,2/g).join(':').toUpperCase()
    

    this.setState(value)

    if (this.props.onChange) 
      event.nativeEvent.text = value
      this.props.onChange(event)
    
  

  render() 
    return <WrappedComponent 
      ...this.props 
      onChange=(event) => this.onChange(event)
      value=this.state.value
    />
  


【讨论】:

【参考方案4】:

在格式化中,您实际上需要 3 个函数,一个用于格式化实际值,第二个用于将格式化值转换回实际值,第三个用于检查到目前为止输入的输入是否有效。例如对于日期输入,输入的字母输入应该被忽略,但同时 99 应该被忽略,因为它不是一个月的有效输入。因此,对于您的特定情况,以下结构应该适合您(在此示例中,inputToValue 函数既检查输入的输入是否有效并根据它设置状态):

formatFunction(cardExpiry = "")
   //expiryDate will be in the format MMYY, so don't make it smart just format according to these requirements, if the input has less than 2 character return it otherwise append `/` character between 2nd and 3rd letter of the input.
   if(cardExpiry.length < 2)
    return cardExpiry;
   
   else
    return cardExpiry.substr(0, 2) + "/" + (cardExpiry.substr(2) || "")
   


inputToValue(inputText)
    //if the input has more than 5 characters don't set the state
    if(inputText.length < 6)
         const tokens = inputText.split("/");
         // don't set the state if there is more than one "/" character in the given input
         if(tokens.length < 3)
            const month = Number(tokens[1]);
            const year = Number(tokens[2]);
            //don't set the state if the first two letter is not a valid month
            if(month >= 1 && month <= 12)
               let cardExpiry = month + "";
               //I used lodash for padding the month and year with  zero               
               if(month > 1 || tokens.length === 2)
                    // user entered 2 for the month so pad it automatically or entered "1/" convert it to 01 automatically
                    cardExpiry = _.padStart(month, 2, "0");   
               
               //disregard changes for invalid years
               if(year > 1 && year <= 99)
                   cardExpiry += year;
               
               this.setState(cardExpiry);
            
         
    


render()
    let cardExpiry = this.state;
    return <TextInput
       value = this.formatFunction(cardExpiry)
       onChangeText=this.inputToValue.bind(this)/>;

【讨论】:

以上是关于React Native:如何使用/使用 <TextInput/> 使格式卡过期?的主要内容,如果未能解决你的问题,请参考以下文章

React Native:如何使用/使用 <TextInput/> 使格式卡过期?

如何使用 react-native 的 TextInput 的 `selectionState` 属性?

如何在 react-native 中使用 zIndex

React Native 如何在 flex 方向行内使用 like <br>

如何在 React Native 中的循环中查找

react-native 如何调用子子组件的方法或者属性