react Input組件Compositionstart和Compositionend事件
前言
Input組件大家都用過,是吧,但是你有沒有想過這樣一個場景,如下圖,我正在搜索數(shù)據(jù)
你組件上注冊了onChange事件,然后邊輸入,底下會顯示你搜索相關(guān)的內(nèi)容,

但是有一個問題就是,輸入中文的時候,你比如打三國的三字,要先輸入san然后才出現(xiàn)三

可問題來了,onChange事件監(jiān)聽的是san,已經(jīng)開始搜索了,其實我們根本不想這樣,我們想的是中文的話,等中文顯示在輸入框,也就是輸入完“三”這個字的時候,才搜索。這個咋辦
這就需要我們今天的主角Compositionstart和Compositionend事件出場了。
Compositionstart和Compositionend事件是啥
compositionstart 事件在用戶開始進行非直接輸入的時候觸發(fā),而在非直接輸入結(jié)束,也即用戶點選候選詞或者點擊「選定」按鈕之后,比如按回車鍵,會觸發(fā) compositionend 事件。
舉個例子,還是上面輸入三這個字的過程,當(dāng)你輸入s的時候,已經(jīng)打開了中文輸入法,此時compositionstart事件觸發(fā)了,當(dāng)你輸入完三并且確認的時候,compositionend事件觸發(fā)。
好了,所以如果你用的組件庫,Input組件沒有優(yōu)化這一項的話,也就是onChange事件在中文輸入法下,應(yīng)該返回的是中文輸入完成,也就是compositionend事件完成的字符,而不是輸入過程的字符,那么就需要組件封裝一下這個邏輯了,如果封裝,我們看下源碼。
本來是打算解析完整的Input組件的,后來想想其實這個組件太簡單了,就只講一下其中的難點吧。
源碼探析解決方案
首先Input組件如下
<input
value={innerValue}
onCompositionStart={handleCompositionStart}
onCompositionEnd={handleCompositionEnd}
onChange={handleChange}
/>
然后我們看下value屬性的formatDisplayValue是什么
// 用來記錄此時是否Compositionstart事件觸發(fā)了,如果觸發(fā)就置為true
// Compositionend結(jié)束就置為false
const composingRef = useRef(false);
// 暴露給
const [value, onChange] = useState<string>('');
const [composingValue, setComposingValue] = useState<string>('');
// 如果啟動了中文輸入法,那么innerValue就是composingValue
// composingValue就是中文輸入的時候比如“三國”,你輸入從“s”到“sanguo”,此時innerValue都是composingValue
// 除了中文輸入法外,innerValue都是value
const innerValue = composingRef.current ? composingValue : value ?? '';
上面可以看到innerValue是最終渲染給input框的value,用戶一般通過onChange事件獲取值,所以 我們在中文輸入的時候,只要不觸發(fā)onChange事件是不是就好了!
關(guān)鍵?。∽钪匾闹R點就是Compositionstart事件觸發(fā)了,代表正在輸入中文,那么onChange事件就不要觸發(fā),所以我們接著把事件的代碼補上
// 開始輸入中文的時候把 composingRef.current 置為true
function handleCompositionStart(e: React.CompositionEvent<HTMLInputElement>) {
composingRef.current = true;
const {
currentTarget: { value },
} = e;
}
// 中文輸入完畢,把composingRef.current置為false,并把此時輸入完的值給handleChange(handleChange會觸發(fā)onChange)
function handleCompositionEnd(e: React.CompositionEvent<HTMLInputElement>) {
if (composingRef.current) {
composingRef.current = false;
handleChange(e);
}
}
function handleChange(e: React.ChangeEvent<HTMLInputElement> | React.CompositionEvent<HTMLInputElement>) {
let { value: newStr } = e.currentTarget;
// 當(dāng)中文輸入的時候,不觸發(fā)onChange事件,觸發(fā)setComposingValue只是為了讓輸入框同步你輸入的text
if (composingRef.current) {
setComposingValue(newStr);
} else {
// 完成中文輸入時同步一次 composingValue
setComposingValue(newStr);
// 中文輸入完畢,此時觸發(fā)onChange
onChange(newStr, { e });
}
}
好了,本文結(jié)束,其實里面還有兩個細節(jié),后面再寫一篇文章說,就是我們input框傳參,可以有defaultValue這個value是外部傳入的,還有props傳入的value,還有組件默認的defalut value,這3個值怎么寫一個hooks去處理,還有就是你們知道input框有種類型是顯示password嗎,這種顯示密碼的input框,輸入文字后顯示的是...如下:

點擊眼睛圖標(biāo)就能看到輸入的文字了,這個是咋辦到的。
以上就是react Input組件Compositionstart和Compositionend事件的詳細內(nèi)容,更多關(guān)于react Input組件事件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
react反向代理使用http-proxy-middleware問題
這篇文章主要介紹了react反向代理使用http-proxy-middleware問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
react-router browserHistory刷新頁面404問題解決方法
本篇文章主要介紹了react-router browserHistory刷新頁面404問題解決方法,非常具有實用價值,需要的朋友可以參考下2017-12-12
使用React和Redux Toolkit實現(xiàn)用戶登錄功能
在React中,用戶登錄功能是一個常見的需求,為了實現(xiàn)該功能,需要對用戶輸入的用戶名和密碼進行驗證,并將驗證結(jié)果保存到應(yīng)用程序狀態(tài)中,在React中,可以使用Redux Toolkit來管理應(yīng)用程序狀態(tài),從而實現(xiàn)用戶登錄功能,需要詳細了解可以參考下文2023-05-05
react-native中ListView組件點擊跳轉(zhuǎn)的方法示例
ListView作為React Native的核心組件,用于高效地顯示一個可以垂直滾動的變化的數(shù)據(jù)列表。下面這篇文章主要給大家介紹了關(guān)于react-native中ListView組件點擊跳轉(zhuǎn)的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-09-09
React Hook 監(jiān)聽localStorage更新問題
這篇文章主要介紹了React Hook 監(jiān)聽localStorage更新問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

