#目次
#概要
この記事は、Reactにおけるイベント処理の仕組みなどについてまとめています。主にReact初心者向けの内容となっています。
また私自身の備忘録としてイベントハンドラについても一覧としてまとめていますので、参考にしてみてください。
#イベント処理とは
イベント処理とは、ユーザが「クリック」や「入力」などの操作が発生したときにプログラム側が行う処理のことを言います。
#Reactのイベント処理
Reactでのイベント処理はDOM要素のイベント処理と非常に似ていますが、いくつかの特徴があります。
- イベントはcamelCaseで名付ける(「onclick」ではなく「onClick」)
- イベントハンドラには文字列ではなく関数を渡す
簡単な例を見てみましょう。特に<button>
タブの中身に注目して見てください。
HTMLの場合
<html>
<script>
const buttonAlert = () => {
alert('Clicked!');
}
</script>
<body>
<button onclick="buttonAlert()">Click me</button>
</body>
</html>
Reactの場合
cnost App = () => {
const buttonAlert = () => {
alert('Clicked!');
}
return(
<button onClick={buttonAlert}>Click me</button>
);
}
<button>
タブの中身がHTMLの場合とReactの場合とではわずかに違いますよね。
ReactでHTMLの場合のように記述してしまうとエラーとなりますので気をつけましょう。
ReactはJavaScriptのライブラリなので、イベント処理ではaddEventListener
を定義し、onClick
などのイベント属性内に記述することは変なのではと疑問に感じる方もいるかもしれません。しかしReact(JSX)では、イベント処理をonClick
等のイベント属性に記述します。なぜこのような記述方法が可能なのかですが、JSXがレンダリングされるとき実際にはaddEventListener
に置換されるそうです。
上記の例のように状態などが無く、必ず同じ結果を返す場合は簡単に表現できます。
しかし状態によって処理に変更が生じる場合はどうなるでしょうか。
###メソッドのbind
はじめに例を見てみましょう。
import React, { Component } from 'react';
class Toggle extends Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// ここに注目
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
export default Toggle;
これはボタンが押されるたびにONとOFFを切り替える機能を実装したプログラムです。
このとき、handleClick()
メソッド内ではthis
を使ってstate
を参照していますが、this
はconstructor
内で使用されているのでhandleClick()
メソッド内でも使用できるように関連付けてあげる必要があります。
このようにconstructor
内でhandleClick()
メソッドをbind
することでthis
を使用できるようになります。
ただメソッドが多くなればなるほど、this.メソッド = this.メソッド.bind(this)
のような宣言も増えますよね。それを回避するため、つまり明示的にbind
を記述しない記述方法があります。
方法その1:ES6のアロー関数をJSX内で記述する方法
方法その2:Class Fields利用する方法
それぞれ見てみましょう。
方法その1
import React, { Component } from 'react';
class Toggle extends Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// bindを書かなくて良い
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={() => this.handleClick()}> {/* ここに注目 */}
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
export default Toggle;
方法その2
import React, { Component } from 'react';
class Toggle extends Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// bindを書かなくて良い
}
handleClick = () => { // ここに注目
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
export default Toggle;
bind
のある場合、方法その1、その2いずれの場合も同じ結果になります。bind
のない場合の方がすっきり見えますし、記述量も少なくて済むので良いですね。
方法その1、その2のような記述ができる理由については、現時点で調べてもよくわからなかったので詳しい方がいればコメントなどで教えてもらえるとありがたいです。私のようによくわからないという人は、そういう仕様と捉えておけば大丈夫かとおもいます。
注意点として方法その2の手法はTC39というJavaScript関係の委員会が提案している手法なのですが、現在Stage3で実験的に行っているそうなので環境的にできない場合もあるかと思います。Create React Appではデフォルトで利用できます。
(補足)
方法その2のようにClass Fieldsを利用すると、クラス構文でconstructor
の宣言も省略することができます。
import React, { Component } from 'react';
class Toggle extends Component {
// ここに注目(this.state → state)
state = {isToggleOn: true};
handleClick = () => {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
export default Toggle;
この場合propsはどう使うのか疑問に思うかもしれませんが、何も宣言せずに必要に応じてthis.props
も利用できます。
#イベントハンドラ一覧
Reactで用いることのできるイベントハンドラはJavaScriptのイベントハンドラに準拠しています。ではどのようなイベントハンドラがあるか見てみましょう。
イベントハンドラ | 説明 |
---|---|
onBlur / onFocus | フォーカスが移動したとき |
onChange | フォームの入力値 / 選択が変更されたとき |
onSelect / onSelectStart | テキストが選択されたとき |
onSubmit / onReset | フォームの送信時 / リセット時 |
onAbort / onError | 画像読み込み時の中断 / エラー |
onLoad / onUnload | ページの読み込み時 / 切り替え時 |
onClick / onDblClick | クリック / ダブルクリックされたとき |
onKeyPress / onKeyDown / onKeyUp | キーの状態に応じる |
onMouseOver / onMouseOut | マウスを乗せたとき / 離したとき |
onMouseDown / onMouseUp | マウスでクリックしたとき |
onMousemove | マウスを動かしているとき |
この辺りは覚えるというよりは、使いたいときに参照する程度にしておけばいいと思います。他にも色々あるので必要に応じて調べて使うようにしましょう。
#まとめ
今回はReactにおけるイベント処理とそのイベントハンドラについてまとめてみました。特に記述方法などの基礎的な部分に関してはしっかり抑えておきましょう。
- イベントはcamelCaseで名付ける(「onclick」ではなく「onClick」)
- イベントハンドラには文字列ではなく関数を渡す
- bindは記述方法によって省略可能
#参考資料