onCompositionStartを使用する時に、気をつけること~React備忘録~


onCompositionStartとonCompositionEndを使うと、入力が確定しているかどうか判別できる。
(表音文字の自然言語の入力を想定する時以外で使用する場合ってあるのかなあ。ボソ)

contenteditableな要素を使用して、入力文字の制御を行いたかったので、今回onCompositionStartとonCompositionEndを使いました。
というのも、入力文字の制御機能を追加すると、日本語入力が確定される前に入力確定されてしまったので。(例えば、「か」と入力しようとすると「ka」となってしまう)

その時に、エラーが発生してしまって、それについての備忘録です。

最初、このようなコードをかきました。

import React, { useState } from 'react'

function InputDiscrimination() {
    const [isInputting, setIsInputting] = useState(false)

    const handleInput = (event) => {
      if (isInputting) {
        console.log('入力中')
      } else {
        console.log('入力確定')
      }
    }

    return (
      <div
        contentEditable="true"
        data-placeholder="入力してください"
        onInput={handleInput}
        onCompositionStart={setIsInputting(true)}
        onCompositionEnd={setIsInputting(false)}
      />
    )
}

export default InputDiscrimination

イケそう!
そう思ってレンダリングすると、、、

Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.

何だと。無限ループしてしまうってどこの行がだ、、、

そこで、onCompositionStartとonCompositionEndをコメントアウトすると、正常にページが読み込めたので、ここの記述が悪いのだろう。
そこで、アロー関数を用いて記述することにしました。

onCompositionStart={() => {setIsInputting(true)}}
onCompositionEnd={() => {setIsInputting(false)}}

こうすると、正常に作動しました。
何でだろう。
調べます。

reactの公式の説明に書いてありました。

一般的に、onClick={this.handleClick} のように () を末尾に付けずに何らかのメソッドを参照する場合、そのメソッドはバインドしておく必要があります。
クラスフィールド構文を使用していない場合、コールバック内でアロー関数を使用することもできます
イベント処理(React公式)

日々精進です。