めっちゃ簡単
import {Component, ChangeEvent, KeyboardEvent} form "react"
export class TextInput extends Component<{
type?: "text"|"email"|"password",
value?: string,
className?: string,
onChange?: (e:ChangeEvent) => void,
onCommit?:(e:KeyboardEvent) => void
}> {
state: {
isComposition: boolean
} = {
isComposition: false
}
render() {
return <>
<input
type={this.props.type}
value={this.props.value}
className={`${this.props.className} defaultClassName`}
onChange={this.props.onChange}
//ここから
onCompositionStart={() => {this.setState({isComposition: true})}}
onCompositionEnd={() =>{ this.setState({isComposition: false})}}
onKeyDown={(e) => {
if(e.key === "Enter" && !this.state.isComposition && this.props.onCommit){
this.props.onCommit(e);
}}
//ここまでが要
/>
</>
}
}
解説
React公式ドキュメントでは
CompositionEvent ハンドラ関数。インプットメソッドエディタ (IME) が新しいコンポジションセッションを開始するときに発火します。
と書いてるが簡単にいうと、変換を開始すると発火するみたい
onCompositionEndとは
CompositionEvent ハンドラ関数。インプットメソッドエディタがコンポジションセッションを完了またはキャンセルするときに発火します。
つまりこれは変換が終わった時に発火するみたい
処理の流れ
- 変換中かどうかの状態をisCompositionという名前のstate変数で保持
- onKeyDownによってキーボードの押下状態を常に監視
- Enterキーが押された&&変換中でない&&this.props.onCommitに関数が設定されてる場合のみthis.props.onCommitを発火する
注意: onCommitの設定は任意にしているためthis.props.onCommitはundefinedにもなり得るので条件に追加している