ゆったりWeb手帳

ReactでonKeyPressを取得する

onKeyPress を取得する

onKeyPressはブラウザでキー入力されたときの動作を制御するために使います。

input で onKeyPress を取得する

例えば、inputタグで、入力後Enterを押して確定する動きをReactで実装すると以下のようになります。

React
const Component = ({text, changeText, sendText}) => {

  const keyPress = (e) => {
    if (e.which === 13) sendText()
  }

  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内にinputtextareaがある場合、イベントはバブリングするので文字列入力時のスペース入力も拾ってしまいます。

この場合は、フォーム要素での入力にevent.stopPropagation()メソッドを使うか、以下のようにdivでイベントを拾ったときに除外します。

React
const keyPress = (e) => {
  if (e.target.tagName !== 'INPUT' && e.target.tagName !== 'TEXTAREA') return false
  if (e.which === 32) mediaControl()
}