版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44481662/article/details/90256989
在React开发项目的过程中,避免不了会用到input标签(比如在登录、录入用户信息等界面),而使用input标签时候,为了体验限制只能输入数字、或者只能输入数字或者字母、或者只能输入英文等限制条件。
今天在这里记录一下在项目中遇到的一个问题,描述如下:
在做用户登录界面,用户登录名字可以是数字、字母或者是数字和字母的组合,在控制用户输入只能是数字或者字母的时候,用IOS的全键盘输入汉字,在还没有输入完成,输入的拼音就直接变成字母带入到input的value值中,代码如下:
、、、、、
onAccountChange(e){
let value = e.target.value;
value = value.replace(/[^\d/a-zA-Z]/g,'')
this.setState({
accountValue: value
})
}
、、、、、、
render() {
return(
)
}
原因: 在input的onChange中监听到input中输入的值的时候进行了正则的判断,而输入中文的拼音时候也会走onChange这个方法,到这个方法做正则的替换时候不知道现在输入的是拼音,直接当成字母来处理了,就出现了Ios全键盘输入拼音时候还没有选择汉字拼音就直接转化成了字母。
解决方法是使用compositionstart+compositionend+input来判断直接输入的还是非直接直接输入
compositionstart:非直接的文字输入时(键盘输入中文的拼音)
compositionend:直接输入文字后(键盘选择真实的汉字)
input:输入内容(输入任何东西)
注:compositionend的调用会在input之后,所以我在实现的时候又做延迟
我解决方如下:
对input标签封装成一个模块,所有需要使用input标签使用这个模块;
首先对模块首次渲染后做input标签的监听:
componentDidMount (){
this.inputRef.addEventListener('compositionstart', function(){//非直接的文字输入时(键盘输入中文的拼音)
this.isCompositions = false;
}.bind(this))
this.inputRef.addEventListener('compositionend', function(){//直接输入文字后(键盘选择真实的汉字)
this.isCompositions = true;
}.bind(this))
this.inputRef.addEventListener('input', function(){
setTimeout(function(){
if(this.isCompositions){//输入的是拼音就不回调输入的内容
this.props.onChange({target:{value:this.inputRef.value}})
}
}.bind(this),100)//延迟回调模块中input中输入的值
}.bind(this));
}
在componentWillReceiveProps函数中重现更新使用正则 替换的值:
componentWillReceiveProps (newProps){
if (newProps.value!=this.state.inputValue) {
this.setState({
inputValue: newProps.value
});
}
}
模块的input的标签的的onChange方法中 不做任何操作,把输入的内容直接赋值模块中input标签的value中:
onChangeInput(e){
this.setState({
inputValue: e.target.value
});
}
实现原理就是:在模块中input标签输入的值只在模块中使用,如果输入拼音时候,只有在选择完汉字后才回调父类的方法把input标签中的内容传输到父类,父类对其中的内容做一些正则替换后再传递给模块(子类),模块(子类)再改变input标签中的value值,从而解决直接使用input的onChange方法中使用正则出现问题。