LoginSignup
0
1

More than 1 year has passed since last update.

[React Native/Web]日本語IMEでTextInput入力制限の件

Posted at

はじめに

こんにちは。久しぶりに投稿させていただきます。今回もReact Nativeの開発ノウハウです。
「この入力欄には数字のみ受け付けてほしい」
こういう要望、よくあるではないか。
React NativeのTextInputでは入力タイプが設定できないが、下記のように実装してたら、入力制限もできる。

<TextInput
  onChangeText={t => setText(t.replace(/[^0-9]/g, ""))}
  value={text}
/>

……けれども、Windows環境で、日本語IMEで入力すると、問題が起きる。

問題点

問題というのは、TextInputにすでに何か入力していた場合、日本語IMEで何かを入力しようとすると(もちろん、日本語を受け付けないようにしている)、既存の文字が消去される。
Expo Snackで動作を見ましょう。
Screenshot 2022-10-18 101557.png
上記のようにTextInputを実装していたら、数字だけ受け付けることになる。
Screenshot 2022-10-18 101746.png
次に日本語IMEで「あいうえお」を入力してみる。「あ」と「い」を押したら、かなが出てこないが、入力欄の「0」が消えた。
Screenshot 2022-10-18 101805.png
つづいて「お」まで押したら、すべての数字が消えた。
この問題は、Windowsに起きるけど、Android/iOSには起きない。ちなみに、ほかの日本語IMEや中国語IMEでも問題が起きる(Google日本語IME・Microsoft中国語IMEで検証済み)。

解決策

なぜこうなるかわからないけど、IMEが原因だとなんとなく理解しているだろう。では解決するにも、IMEに何とかすることですね。
W3Cはたくさんのキーボード押すイベントを定義している。そのうち、IME入力も含んでいる。
https://www.w3.org/TR/uievents-key/#keys-composition
React Native TextInputでは、上記の一部を利用していて、キーボード押すイベント(onKeyPress)に入っている。そして、onKeyPressの発火タイミングはonChangeTextより先。そこで、onKeyPressでIME入力かどうかを判別し、YESの場合、IME入力自体を無視すれば、問題回避できるだろう。

ではさっそくやってみましょう。

<TextInput
  onKeyPress={e => {
    isIme = e.key == "Process"; //IMEで入力する時、値は常に"Process"
  }}
  onChangeText={t => {
    if (!isIme) setText(t.replace(/[^0-9]/g, ""));
  }}
  value={text}
/>

このように実装していれば、既存の文字が消去される問題が回避できる。
Screenshot 2022-10-18 105249.png
「あいうえおかきくけこ」まで押しても、数字たちが消去されていない。

最後に

この記事はあくまでも私個人の経験です。間違っているところ、もっと良い方法がございましたら、ぜひ教えてください。

参考資料

https://stackoverflow.com/questions/32946793/react-native-textinput-that-only-accepts-numeric-characters
https://www.w3.org/TR/uievents-key/#keys-composition

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1