... <input ref="inputTest" type="text" placeholder="test" value={this.state.val} onChange={this.inputValue}/> ... inputValue(e){ this.setState({ val:e.target.value }) }
以上这段代码,相信你们再熟悉不过了,react 受控组件的最简单的栗子,controlled input组件。React的事件,包括上面咱们使用的onChange事件,都属于React的合成事件
,是非浏览器原生的,它是对浏览器原生事件的封装事件。react合成事件中,onChange事件相似于原生的input事件,只要按键就会触发,这在pc上面或者英文输入法中不会有任何问题,可是对于移动端输入时须要切换中文输入法或者其余不一样输入法的其余语言的用户来讲,是有问题的。好比上面这段最简单的代码,咱们想要输入中文,好比"事件",咱们须要在手机键盘按键'shijian',每按一次键都会触发onChange事件,而后会发现输入框的内容已经输入了英文字母,这不是咱们须要的结果。那怎么解决呢?接下来,咱们的主角出场--compositionEvent。组合事件能够帮助咱们解决这个问题,能够参看组合事件参考文档。react
咱们仍是以输入中文为例,你们会发现,在移动设备中,中文的输入其实分为三个步骤(pc上其实也是同样),1:开始,2:敲键盘,3:点击选择中文。这个compositionEvent组合事件就是分拆了不一样的步骤的事件的组合,这个组合事件是由compositionStart
,compositionUpdate
和compositionEnd
三个事件的组合,Start和End事件只执行一次,Update会执行屡次,只要没有选中中文以前,触发update事件,选中须要的选中的文字,就会触发end事件,一个组合事件完成,以此循环。了解了组合事件这个原理后,解决方案就不难理解了吧。浏览器
使用这种方式就基本上与pc浏览器的效果就一致了,请看以下代码,只添加了组合事件中End的监听,意味着若咱们完成输入最后一步选中操做后,才会触发该监听。你们确定会疑问,这不就是的onInput效果吗,那不就可以支持到controlled组件的方式,对不起,真不行,由于输入确实完美契合,可是删除操做,就没法触发这个监听了。因此,若是不加上onChange事件的配合,那就使用uncontrolled组件的方式吧函数
<input ref="inputTest" type="text" placeholder="测试" onCompositionEnd={this.handleComposition} />
上面已经提到controlled组件的解决方式了,那就是与onChange事件进行配合,那具体如何配合呢,请看代码以下:测试
<input ref="inputTest" type="text" placeholder="测试" onCompositionStart={this.handlingComposition} onCompositionUpdate={this.handlingComposition} onCompositionEnd={this.handleComposition} onChange={this.inputValue}/> ... handlingComposition(){ this.isCompositionEnd = false; } handleComposition(e){ this.isCompositionEnd = true; } inputValue(e){ if(this.isCompositionEnd){ this.setState({ val:e.target.value }) } }
以上代码会存在一点小问题,须要确保onCompositionEnd在onChange事件前触发,一旦有的浏览器存在兼容问题,二者的执行顺序相反,会致使onChange事件永不触发,所以,最好在handleComposition函数中重复执行一次onChange中的逻辑,避免出现兼容问题。this