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