只接受数字字符的 React NativeTextInput

我需要有一个反应本机 TextInput组件,将只允许数字字符(0-9)输入。我可以将 keyboardType设置为 numeric,这样除了句点(.)之外,我几乎可以输入到那里.但是,这并不能阻止将非数字字符粘贴到字段中。

到目前为止,我想到的是使用 OnChangeText事件来查看输入的文本。从文本中删除任何非数字字符。然后将文本放在状态字段中。然后通过它的 Value属性更新 TextInput。下面是代码片段。

<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})
}

这似乎工作,但它似乎是一个黑客。有没有其他方法来做到这一点?

273523 次浏览

这是在专门开发这样一个组件(或 TextInput 上的属性)之前进行此操作的正确方法。

网页有“数字”类型的输入元素,但这是基于网络和反应-本地不使用网络视图。

您可以考虑将该输入创建为它自己的一个响应组件(可以调用 NumberInput) : 这将允许您重用它,甚至可以开放源代码,因为您可以创建许多具有不同值过滤器/检查器的 TextInput。

立即更正的缺点是要确保给予用户正确的反馈,以防止混淆他的价值发生了什么

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

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

你可以这样做。它将只接受数字值,并限制为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 });
}

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

<TextInput autoCapitalize={'none'} maxLength={10} placeholder='Mobile Number'  value={this.state.mobile} onChangeText={(mobile) => this.onChanged(mobile)}/>

改变方法:

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 });
}
}

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

对 onTextChange 处理程序使用:

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

性能测试: https://jsperf.com/removing-non-digit-characters-from-a-string

使用 RegExp 替换任何非数字。注意下一个代码会给你他找到的第一个数字,所以如果用户粘贴一个段落有一个以上的数字(xx.xx)的代码将给你的第一个数字。这将有助于如果你想要的东西,如价格,而不是移动电话。

对 onTextChange 处理程序使用:

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

我在 iOS 系统中也遇到了同样的问题,使用 onChangeText 事件来更新用户输入的文本值,但我无法更新 TextInput 的值,所以用户仍然可以看到他输入的非数字字符。

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

我发现解决这个问题的唯一方法是使用发生在 onChangeText 事件之前的 keyPress 事件,并在其中使用 setState 将状态的值更改为另一个完全不同的状态,在调用 onChangeText 事件时强制重新呈现。虽然不是很满意,但还是奏效了。

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

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

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

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

对于 Decimal/浮点数,只需尝试此操作

    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 });

}

验证输入的函数:

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')}
/>

我希望这能有所帮助。

我写了这个函数,我发现它有助于防止用户输入任何我不愿意接受的内容。我还使用了 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块确保他们可以输入尽可能多的数字,因为他们想在小数位之前,但只有两个小数位后的点。

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

<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
}


提醒那些遇到“ onChangeText”不能像 iOS 上期望的那样改变 TextInput 值的问题的人: 这实际上是 ReactNative0.57.1版本中的一个 bug。参考: https://github.com/facebook/react-native/issues/18874

if (!/^[0-9]+$/.test('YourString')) {
console.log('Enter Only Number');
} else {
console.log('Success');
}

React NativeTextInput 为 keyboardType 道具提供以下可能的值: 违约 电话簿 小数点后 数字 电邮地址 电话本

因此,对于您的情况,您可以使用 keyboardType = ‘ number-pad’来只接受数字

所以,

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

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

有关详情,请参阅文本输入的官方文档链接: Https://facebook.github.io/react-native/docs/textinput#keyboardtype

第一个解决方案

可以将 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>

在第一种情况下,句读包括 ex:-.-

第二个解决方案

使用正则表达式删除句读。

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

请查看零食链接

Https://snack.expo.dev/@vishaldhanotiya/numeric-keyboard

const [text, setText] = useState('');


const onChangeText = (text) => {
if (+text) {
setText(text);
}
};


<TextInput
keyboardType="numeric"
value={text}
onChangeText={onChangeText}
/>

这应该保存从物理键盘

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

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

然后用空格代替点

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

console.log("text",text)
}

我想,

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

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

如果有人正在寻找允许使用 数字键盘验证输入只允许一个小数点的解决方案,那么下面就是我为了实现这一点而写的。我也想有 用点(.)代替逗号(,),因为这是我保存到数据库的方式,但你可以删除它-它是可选的。

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>

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

如果你使用钩子:

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

假设文本使用 useState hook 进行初始化

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

如果你添加以下行,那么当你开始输入时,它只会打开数字键盘,而不会打开字符键盘:

 <TextInput
placeholder="Enter Mobile No."
onChangeText={setMobileNumber}
value={mobileNumber}
keyboardType="number-pad"
maxLength={12}
/>