【问题标题】:React Native TextInput that only accepts numeric charactersReact Native TextInput 只接受数字字符
【发布时间】:2016-01-02 00:04:12
【问题描述】:

我需要一个 React Native TextInput 组件,它只允许输入数字字符 (0 - 9)。我可以将keyboardType 设置为numeric,这几乎可以让我在那里输入,除了句点 (.)。然而,这并不能阻止将非数字字符粘贴到字段中。

到目前为止,我想出的是使用OnChangeText 事件来查看输入的文本。我从文本中删除了所有非数字字符。然后将文本放在状态字段中。然后通过Value 属性更新TextInput。代码如下:sn-p。

<TextInput 
  style={styles.textInput}
  keyboardType = 'numeric'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/> 

onTextChanged(text) {
  // code to remove non-numeric characters from text
  this.setState({myNumber: text})
}

这似乎有效,但它似乎是一个 hack。有没有其他方法可以做到这一点?

【问题讨论】:

  • 从来没有让这个例子工作。您是否设法以其他方式解决它?
  • 请注意,从 React Native 0.54 开始,此处建议的大多数答案都已失效:github.com/facebook/react-native/issues/18874(至少达到 0.56,这是撰写本文时的最新版本)。
  • @sumitkumarpradhan 该博客文章建议将键盘类型设置为“数字”,这实际上不会阻止文本输入。你可以复制粘贴任何你想要的东西到那里。
  • 我在 TextInput 中使用 keyboardType='numeric' 属性仅显示数字键盘 (duh),并使用正则表达式 text.replace(/[^0-9]/g, '') 替换文本,如下所示,以防止任何人在 TextInput 中粘贴字符串。到目前为止在 React Native v0.62 上运行良好

标签: react-native


【解决方案1】:

使用 RegExp 替换任何非数字比使用带有白名单的 for 循环更快,就像其他答案一样。

将此用于您的 onTextChange 处理程序:

onChanged (text) {
    this.setState({
        mobile: text.replace(/[^0-9]/g, ''),
    });
}

在这里进行性能测试:https://jsperf.com/removing-non-digit-characters-from-a-string

【讨论】:

  • 如何使用这种方法只允许英文字母中的字母?
  • @CraZyDroiD 只需调整正则表达式。如果您只想匹配 A-Z,则需要类似 text.replace(/[^A-Za-z]/g, '')
  • 还将 keyboardType='numeric' 属性传递给 TextInput 字段。
  • 它工作得很好,但是我们可以以任何方式克服一点闪烁
  • 随机,但您也可以通过 autoCompleteType 为 Android 自动填充字段类别 (Android) + textContentType 在 iOS 设备上执行相同的操作。
【解决方案2】:

你可以这样做。它只接受数值,并根据您的意愿限制为 10 个数字。

<TextInput 
   style={styles.textInput}
   keyboardType='numeric'
   onChangeText={(text)=> this.onChanged(text)}
   value={this.state.myNumber}
   maxLength={10}  //setting limit of input
/>

您可以通过在页面中编写以下代码来查看输入的值:

{this.state.myNumber}

在 onChanged() 函数中,代码如下所示:

onChanged(text){
    let newText = '';
    let numbers = '0123456789';

    for (var i=0; i < text.length; i++) {
        if(numbers.indexOf(text[i]) > -1 ) {
            newText = newText + text[i];
        }
        else {
            // your call back function
            alert("please enter numbers only");
        }
    }
    this.setState({ myNumber: newText });
}

我希望这对其他人有帮助。

【讨论】:

  • 小修正:onChanged(text){ var newText = '';变数 = '0123456789'; if(text.length -1) { newText = newText + text[i]; } this.setState({ myNumber: newText }); } }
  • 很好的答案,但你为什么讨厌数字'9'
  • 因为7讨厌9?
  • 有没有办法防止闪烁?
  • 你是最棒的人
【解决方案3】:

在专门开发此类组件(或 TextInput 上的属性)之前,这是正确的做法。

Web 的 input 元素具有“数字”类型,但这是基于 Web 的,并且 react-native 不使用 Web 视图。

您可以考虑将该输入创建为自己的反应组件(可能称为 NumberInput):这将使您能够重用它,甚至可能开源它,因为您可以创建许多具有不同值过滤器/检查器的 TextInput .

立即纠正的缺点是确保向用户提供正确的反馈,以防止混淆他的价值发生了什么

【讨论】:

  • 我如何设置国家代码。(即)我可以在文本输入组件中使用任何道具设置国家代码
【解决方案4】:

React Native TextInput 提供了具有以下可能值的键盘类型道具: 默认 数字键盘 小数点 数字 电子邮件地址 手机垫

因此,对于您的情况,您可以使用 keyboardType='number-pad' 仅接受数字。这不包括“。”

所以,

<TextInput 
  style={styles.textInput}
  keyboardType = 'number-pad'
  onChangeText = {(text)=> this.onChanged(text)}
  value = {this.state.myNumber}
/>

是你必须在你的情况下使用的。

更多详情请参考 TextInput 的官方文档链接: https://facebook.github.io/react-native/docs/textinput#keyboardtype

【讨论】:

    【解决方案5】:

    第一个解决方案

    您可以将keyboardType = 'numeric' 用于数字键盘。

      <View style={styles.container}>
            <Text style={styles.textStyle}>Enter Number</Text>
            <TextInput
              placeholder={'Enter number here'}
              style={styles.paragraph}
              keyboardType="numeric"
              onChangeText={value => this.onTextChanged(value)}
              value={this.state.number}
            />
          </View>
    

    在第一种情况下,标点符号包括:- .-

    第二个解决方案

    使用正则表达式去除标点符号。

     onTextChanged(value) {
        // code to remove non-numeric characters from text
        this.setState({ number: value.replace(/[- #*;,.<>\{\}\[\]\\\/]/gi, '') });
      }
    

    请查看零食链接

    https://snack.expo.io/@vishal7008/numeric-keyboard

    【讨论】:

    • 这很好,但如果你有一个物理键盘,它就不起作用了。
    【解决方案6】:

    只允许使用正则表达式的数字

    <TextInput 
      keyboardType = 'numeric'
      onChangeText = {(e)=> this.onTextChanged(e)}
      value = {this.state.myNumber}
    /> 
    
    onTextChanged(e) {
      if (/^\d+$/.test(e.toString())) { 
        this.setState({ myNumber: e });
      }
    }
    

    您可能希望进行多个验证

    
    <TextInput 
      keyboardType = 'numeric'
      onChangeText = {(e)=> this.validations(e)}
      value = {this.state.myNumber}
    /> 
    
    numbersOnly(e) {
        return /^\d+$/.test(e.toString()) ? true : false
    }
    
    notZero(e) {
        return /0/.test(parseInt(e)) ? false : true
    }
    
    validations(e) {
        return this.notZero(e) && this.numbersOnly(e)
            ? this.setState({ numColumns: parseInt(e) })
            : false
    }
    
    

    【讨论】:

    • 前两个函数不用创建,直接使用即可:validations(value: string) { return /0/.test(value) &amp;&amp; /^\d+$/.test(value) ? this.setState({ numColumns: value }) : false; }
    • @FrederikoCesar 了解单一责任原则
    【解决方案7】:

    验证输入的功能:

    validateInputs(text, type) {
    let numreg = /^[0-9]+$/;
      if (type == 'username') {
        if (numreg.test(text)) {
          //test ok
        } else {
          //test not ok
        } 
      }
    }
    
    
    
    <TextInput
       onChangeText={text => this.validateInputs(text, 'username')}
    />
    

    我希望这会有所帮助。

    【讨论】:

    • 那是更有效的方法,应该遵循它而不是循环方法
    【解决方案8】:

    提醒那些遇到“onChangeText”无法在 iOS 上按预期更改 TextInput 值的问题:这实际上是 ReactNative 中的一个错误,已在 0.57.1​​ 版本中修复。参考:https://github.com/facebook/react-native/issues/18874

    【讨论】:

    • 这应该是评论而不是答案
    • 抱歉,我没有足够的声誉来评论这个问题,所以我最终得到了答案,希望能引起人们对寻求可行解决方案的关注。
    • 公平点。我看到一个人需要 50 声望才能发表评论。遗憾的是,我无法取消该限制,但我可以给你 10 点声望,并希望取消一些限制。
    • 再花 10 次获得评论条款...干杯 @Wing
    • 谢谢 :) @VenkateshSomu
    【解决方案9】:
    const [text, setText] = useState('');
    
    const onChangeText = (text) => {
      if (+text) {
        setText(text);
      }
    };
    
    <TextInput
      keyboardType="numeric"
      value={text}
      onChangeText={onChangeText}
    />
    

    这应该从物理键盘保存

    【讨论】:

    • 谢谢,我建议将 if(+text) 替换为 if (+text || text == "") 以允许空输入
    • Op 明确表示他们不想允许“.”在输入中。
    【解决方案10】:
    if (!/^[0-9]+$/.test('YourString')) {
      console.log('Enter Only Number');
    } else {
        console.log('Success');
    }
    

    【讨论】:

    • !/^[0-9]+$/.test('123456askm') 它将检查输入字符串是否为数字 .test(Your Value )
    • 您好,请详细说明您的回答,说明为什么这可以解决 OP 的问题。这将有助于 OP 和该网站的未来访问者。谢谢!
    • 这根本不能回答问题。
    【解决方案11】:
    <TextInput autoCapitalize={'none'} maxLength={10} placeholder='Mobile Number'  value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>
    

    和 onChanged 方法:

    onChanged(text){
       var newText = '';
       var numbers = '0123456789';
       if(text.length < 1){
         this.setState({ mobile: '' });
       }
       for (var i=0; i < text.length; i++) {
            if(numbers.indexOf(text[i]) > -1 ) {
                 newText = newText + text[i];
            }
            this.setState({ mobile: newText });
        }
    }
    

    【讨论】:

    • 您的解决方案虽然解决了我的问题,但会产生警告:"This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property 'type' on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist(). See fb&gt;react-event-pooling for more information." 我不知道该怎么办。你能帮忙吗?
    • @Mike 某些事件可能会导致此问题,您能否通过 jsfiddle 或 rnplay.org 分享您的组件代码
    • 我在这里发表评论后不久就解决了这个问题,但不幸的是可以弄清楚问题所在。
    • 使用正则表达式会是更明智的选择
    【解决方案12】:

    我在 iOS 中遇到了同样的问题,使用 onChangeText 事件更新用户键入的文本的值我无法更新 TextInput 的值,所以用户仍然会看到非数字字符他打字。

    这是因为,当按下非数字字符时,状态不会改变,因为 this.setState 将使用相同的数字(删除非数字字符后保留的数字),然后 TextInput 不会重新呈现。

    我发现解决这个问题的唯一方法是使用在 onChangeText 事件之前发生的 keyPress 事件,并在其中使用 setState 将状态值更改为另一个完全不同的值,强制在 onChangeText 时重新渲染事件被调用。对此不太满意,但它确实有效。

    【讨论】:

      【解决方案13】:

      这是我的另一个简单答案,即使用正则表达式仅接受文本框中的数字。

      onChanged(text){
          this.setState({ 
               myNumber: text.replace(/[^0-9]/g, '') 
          });
      }
      

      【讨论】:

        【解决方案14】:

        我编写了这个函数,我发现它有助于防止用户输入我愿意接受的任何内容。我还使用了 keyboardType="decimal-pad" 和我的 onChangeText={this.decimalTextChange}

          decimalTextChange = (distance) =>
        {
            let decimalRegEx = new RegExp(/^\d*\.?\d*$/)
            if (distance.length === 0 || distance === "." || distance[distance.length - 1] === "."
                && decimalRegEx.test(distance)
            ) {
                this.setState({ distance })
            } else {
                const distanceRegEx = new RegExp(/^\s*-?(\d+(\.\d{ 1, 2 })?|\.\d{ 1, 2 })\s*$/)
                if (distanceRegEx.test(distance)) this.setState({ distance })
            }
        }
        

        第一个 if 块是针对用户删除所有文本、使用小数点作为第一个字符或尝试输入多个字符时的错误处理小数点后,第二个 if 块确保他们可以在小数点前输入任意数量的数字,但在小数点后最多只能输入两位小数。

        【讨论】:

        • 这很好,但小数点后我不能得到任何数字?允许否定也很好,例如-3.14
        【解决方案15】:

        使用正则表达式替换任何非数字。注意下一个代码会给你他找到的第一个数字,所以如果用户粘贴一个包含多个数字(xx.xx)的段落,代码会给你第一个数字。如果您想要价格之类的东西,而不是手机,这将有所帮助。

        将此用于您的 onTextChange 处理程序:

        onChanged (text) {
            this.setState({
                number: text.replace(/[^(((\d)+(\.)\d)|((\d)+))]/g,'_').split("_"))[0],
            });
        }
        

        【讨论】:

          【解决方案16】:

          您可以使用正则表达式删除非数字字符

          onTextChanged (text) {
              this.setState({
                  myNumber: text.replace(/\D/g, ''),
              });
          }
          

          【讨论】:

            【解决方案17】:

            我创建了一个组件来解决这个问题:

            https://github.com/amirfl/react-native-num-textinput

            【讨论】:

              【解决方案18】:

              仅适用于小数/浮点数试试这个

                  onChangeMyFloatNumber(text){
              let newText = '';
              let numbers = '0123456789.';
              
              for (var i=0; i < text.length; i++) {
                  if(numbers.indexOf(text[i]) > -1 ) {
                      newText = newText + text[i];
                      if(text[i]=="."){
                        numbers = '0123456789'
                      }
                  }
                  else {
                      // your call back function
                      alert("please enter numbers only");
                  }
              }
              this.setState({ MyFloatNumber: newText });
              

              }

              【讨论】:

                【解决方案19】:

                如果有人正在寻找允许使用数字键盘但也验证输入以只允许一个小数点的解决方案,那么下面是我为实现这一目标而写的内容。我还希望将 comma(,) 替换为 dot(.),因为这是我将其保存到数据库的方式,但您可以将其删除 - 它是可选的。

                const [decimalInput, setDecimalInput] = useState('')
                const validator = /^[+-]?\d*(?:[.,]\d*)?$/;
                
                function onNumberInputChange(text){
                        if (validator.test(text)){
                            text = text.replace(",",".") //this is optional
                            setDecimalInput(text);
                        }
                        else{
                            //this will remove the last character as it didn't succeed validation
                            setDecimalInput(text.substring(0, text.length - 1));
                        }
                    }
                

                和文本输入组件初始化如下:

                <TextInput
                                style={{textAlign: 'center'}}
                                value = {decimalInput}
                                onChangeText={(text) => {
                                  setDecimalInput(text);
                                  onNumberInputChange(text);
                                }}
                                placeholder={"type decimal value here..."}
                                keyboardType="numeric"
                                placeholderTextColor="#ccc">
                </TextInput>
                

                也许你们中的一些人需要同样的方法。

                【讨论】:

                  【解决方案20】:

                  我认为,

                  onChangeText((val:string) => 
                      isNaN(Number(val))
                         ? val.substr(0, val.length - 1)
                         : val
                  )
                  // 0     > true
                  // 0.    > true
                  // 0.3   > true
                  // -     > false
                  // .     > false
                  // 0.4-  > false
                  // -1.3  > true
                  

                  此代码将检查“这不是数字吗?”并且,如果最后一个字符是错误的,请删除最后一个单词。

                  【讨论】:

                    【解决方案21】:

                    如果你使用钩子:

                    <TextInput
                    onChangeText={text=> setMyNumber(text?.replace(/[^0-9]/g, ''))}
                    ....
                    />
                    

                    假设文本是使用 useState 钩子初始化的

                    const [myNumber,setMyNumber]=React.useState(');
                    

                    【讨论】:

                      【解决方案22】:

                      怎么样

                      onChangeText={(val) => {  
                           if(!isNaN(val)){
                             //setValue()
                           }
                        }
                      keyboardType="numeric"
                      

                      这将检查数字是否不是,不是数字,然后才会设置文本。

                      【讨论】:

                      • OP 明确表示他们不想要“。”被接受。
                      【解决方案23】:

                      将您的键盘类型更改为数字

                      <TextInput
                      onChangeText={this.onChangeText}
                       keyboardType={"numeric"}
                      />
                      

                      然后用空格替换点

                      onChangeText=(value)=>{
                          let text = value.replace(".", '');
                                    if (isNaN(text)) {
                                      // Its not a number
                                      return
                                    }
                          
                          console.log("text",text)
                          }
                      

                      【讨论】:

                      • OP 特别提到这是问题中的非解决方案。
                      猜你喜欢
                      • 2011-09-12
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2022-12-23
                      • 2017-03-30
                      • 1970-01-01
                      相关资源
                      最近更新 更多