【React】 inputでEnterキー押下時、日本語変換のものかどうか判定する


フロントエンドエンジニアの茶木です。

あまり多くはないですが、input 入力中に Enter キーを検出したい場合があります。

たとえば input の入力内容を元に、独自のオートコンプリート(サジェスト)のリストを表示するといった場合です。こういったケースでは、input にフォーカスを保持しつつ、キーボードからリストを選択して Enter キーを入力するようなインターフェースになります。

キーボード入力の発火は onKeydown で取得できます。

<input onKeydown={(e) => onKeydown(e.key)}/>

そして、キーコードが取得できるのでキーボード入力の振り分けができます。

const [text, setText] = useState("");
const [index, setIndex] = useState(0);
const list = useMemo(() => getAutocompleteList(text), [text]);
const selectPrevItem = () => setIndex((index + list.length - 1) % list.length);
const selectNextItem = () => setIndex((index + 1) % list.length);

const onKeydown = (key: string) => {
  switch (key) {
    case "Enter":
      onSubmit(list[index]);
      break;
    case "ArrowUp":
      selectPrevItem();
      break;
    case "ArrowDown":
      selectNextItem();
      break;
    default:
      break;
  }
};

return (
  <div>
    <input 
      type="text"
      value={text}
      onChange={(e) => setText(e.target.value)}
      onKeydown={(e) => onKeydown(e.key)}
    />
    <AutocompleteList list={list} index={index} />
  </div>
);

AutoCompleteList は index が現在選択中のアイテムを指す、オートコンプリートの list を表示するコンポーネントだと思ってください。

これでキーボードの Enter が取得できそうですね。

日本語入力の際の決定のEnterキーはスキップしたい

実は落とし穴があって、日本語入力の際の変換から決定で押す Enterキーでも onKeydown が発火してしまうので変換決定時に submit が走ってしまうのです。これは想定していた動作とは違いますね。

やっと本題です。日本語入力の際の Enterキー入力と、そうでない Enterキー入力を区別するにはどうするか?

return (
  <input 
    onCompositionStart={startComposition}
    onCompositionEnd={endComposition}
  >
)

onCompositionStart と onCompositionEnd

input のプロパティのonCompositionStart と onCompositionEnd を使います。それぞれ日本語入力の開始と終了時に発火します。

const [composing, setComposition] = useState(false);
const startComposition = () => setComposition(true);
const endComposition = () => setComposition(false);

const onKeydown = (key: string) => {
  switch (key) {
    case "Enter":
      if(composing) break;
      onSubmit(list[index]);
      break;
      :
  }
};

これで日本語変換中かどうか判定できるので、日本語変換中はsubmit しないように処理を skip させられます。

ほかにも、キーボードの入力からフリガナを内部で取得したりするようなものにも使えるかもしれませんね。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Chaki Hironori

webライターもやってるフロントエンドエンジニアです。Reactは自信があります。またデザイン畑の出身で、気持ちのいいアニメーションやインタラクティブな表現は丁寧に手掛けます。好きなものは中南米の遺跡で、スペイン語が少しできます。