- 问题描述:正常情况下input在微软输入法输入英文和符号都没问题,但在我们使用拼音并且有校验的情况下会出现奇怪的现象,拼音输入是一个过程,确切的说,在这个过程中,你输入的每一个字母都触发了 onChange 事件,而你输入过程中的这个产物在校验中被吃掉了,留下了一坨空字符串,所以就发生了那个神奇的现象。
- 关键属性:componsitonstart和componsitonend。就是当你开始使用输入法进行新的输入的时候,会触发 compositionstart ,中间过程其实也有一个函数 compositionupdate,顾名思义,输入更新时会触发它;当结束输入法输入的时候,会触发 compositionend。
- 解决方案:重写input组件,新增onComponsitonStart和onComponsitonEnd属性,定义一个参数lock,通过lock值去出发input的onChange动作,而lock只有在componsitonend下才有效,也就是说通过手动去判断我们的输入是否结束。(不同浏览器下componsitonstart、compositionupdate、componsitonend的执行顺序会有差异)
const RuleInput = () => {
const [inputValue, setInputValue] = useState('');
let lock = false;
const inputRef = useRef();
function handleChange(e) {
console.log(e);
if (e.type === 'compositionend') {
lock = false;
if (navigator.userAgent.indexOf('Chrome') > -1) {
onchange(e);
};
return
}
lock = true;
}
const onchange = (e) => {
console.log(lock);
const { value } = e.target;
if (!lock) {
inputRef.current.value = value.replace(/[^a-zA-Z0-9\u4E00-\u9FA5]/g, '');
}
}
const onchangeAntd = (e) => {
console.log(e.target.value);
const val = e.target.value.replace(/[^a-zA-Z0-9\u4E00-\u9FA5]/g, '');
setInputValue(val);
}
return (
<>
<input
ref={inputRef}
type="text"
placeholder="请输入"
maxLength={20}
onChange={onchange}
onCompositionStart={handleChange}
onCompositionEnd={handleChange}
/>
<Input
type="text"
value={inputValue}
placeholder="请输入"
maxLength={20}
onChange={onchangeAntd}
/>
</>
)
}