onKeyPress を取得する
onKeyPressはブラウザでキー入力されたときの動作を制御するために使います。
input で onKeyPress を取得する
例えば、
input
タグで、入力後Enterを押して確定する動きをReactで実装すると以下のようになります。React
const Component = ({text, changeText, sendText}) => {
const keyPress = (e) => {
if (e.which === 13) sendText()
if (e.key === 'Enter') setChange()
}
return (
<React.Fragment>
<input type='text' value={text} onChange={(e) => changeText(e)} onKeyPress={(e) => keyPress(e)}>
</React.Fragment>
)
}
この例では、入力後Enterを入力すると入力された文字列が送信されます。IME変換確定時のEnterは無視されます。
div で onKeyPress を取得する
上記`input`のような場合は通常フォーカスされた状態で使用するので入力受付時も問題ないですが、そうではない場合は注意が必要です。
画面制御やメディアの再生、停止をキーボードでも操作できるようにするには親要素(`div`など)でイベントを拾わなければなりません。
この場合は、
tabIndex
を指定してマウントされたときにフォーカスするようにします。React
const Component = ({mediaControl}) => {
const keyPress = (e) => {
if (e.which === 32) mediaControl() // スペースの入力を拾う
}
return (
<React.Fragment>
<div onKeyPress={(e) => keyPress(e)} tabIndex='0'>
<AppComponent />
</div>
</React.Fragment>
)
}
上記例では、スペースキーでメディアの再生を停止します。
しかし、
AppComponent
内にinput
やtextarea
がある場合、イベントはバブリングするので文字列入力時のスペース入力も拾ってしまいます。この場合は、フォーム要素での入力に
event.stopPropagation()
メソッドを使うか、div
でイベントを拾ったときに除外します。React
const keyPress = (e) => {
e.stopPropagation()
}
React
const keyPress = (e) => {
if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') return false
if (e.which === 32) mediaControl()
}
TypeScriptを使う
onKeyPressイベントのTypeScriptの型は
KeyboardEvent<HTMLInputElement>
です。最初の例をTypeScriptで書くと以下のようになります。
React
const Component = ({text, changeText, sendText}) => {
const keyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.which === 13) sendText()
}
return (
<React.Fragment>
<input type='text' value={text} onChange={(e) => changeText(e)} onKeyPress={(e) => keyPress(e)}>
</React.Fragment>
)
}
キーの判別
上記の例はキーの
charCode
を用いて判別を行なっていますが、キーのname
やcode
などで判別する方法もあります。注意点はすべてのブラウザでキーのコードや名前が同じという保証はないので、実際に使用する場合は想定される環境で動作するか確認することをおすすめします。