tです。
今回は、JavaScriptのViewのライブラリである、Reactについて書きます。
Reactで、JavaScriptのdocumentやwindowのイベントを扱う方法について説明します。
React及びES2015以降の構文をある程度理解している前提で進めます。ご了承ください。
Reactのイベント記述について
Reactを利用してイベントを記述する場合、以下のようにJSX記法でイベントを設定します。
1 2 3 |
<button onClick={() => console.log( 'clicked' )}> Click! </button> |
しかし、documentやwindowは元々存在するオブジェクトなので、少し工夫をする必要があります。
通常なら...
通常、documentやwindowにイベントを割り当てる場合は、次のように行います。次のようにすることで、ウィンドウの大きさを変えると、コンソールにイベントオブジェクトの内容が表示されます。
別のリスナーを入れ替えて割り当てる場合は、イベント解除も考える必要があります。
1 2 3 4 5 6 |
// リスナー定義 const listener = (event) => console.log(event); // イベント設定 window.addEventListener('resize', listener); // イベント解除 window.removeEventListener('resize', listener); |
JSXでdocumentやwindowにイベントを割り当てると...
JSX記法で、documentやwindowのイベントを扱えるようにしたのが、以下のコードです。通常の場合と同じように、ウィンドウの大きさを変えると、コンソールにイベントオブジェクトの内容が表示されます。
これだと、onResizeで割り当てているリスナーを入れ替えても、自動で元のリスナーのイベント解除を行います。イベント解除を考える必要がなくなるわけです。
1 2 3 4 |
<EventListener eventTarget={window} onResize={(event) => console.log(event)} /> |
EventListenerコンポーネントは、以下のように作成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import React from 'react'; export default class EventListener extends React.Component { static propTypes = { eventTarget: React.PropTypes.object.isRequired, }; componentDidMount() { // イベントの設定 this.getListeners().forEach( ( [ type, listener ] ) => { this.props.eventTarget.addEventListener( type, listener ); } ); } componentWillUnmount() { // イベントの設定解除 this.getListeners().forEach( ( [ type, listener ] ) => { this.props.eventTarget.removeEventListener( type, listener ); } ); } getListeners() { // propsから、イベント名と関数を抽出 return Object .keys( this.props ) .filter( key => key.startsWith( 'on' ) ) .map( key => [ key.slice( 2 ).toLowerCase(), this.props[key] ] ); } render() { return null; // 何も描画しない } } |
ネットで調べると、componentDidMount・componentWillUnmountを利用して、イベントの登録・解除を行えば良いということがわかりました。
汎用的に使えるコンポーネントにしたかったので、propsに渡されたonで始まるkeyの値をすべてイベントとして扱うようにしました。
なので、EventTargetインターフェースを持つ(addEventListenerとremoveEventListenerが利用できる)オブジェクトであれば、EventListenerコンポーネント自体がイベントを知らなくても使うことができます。
ちなみに
Reactとは直接関係ないですが、今回、記事にするにあたって、EventListenerコンポーネントをLodashを使わないコードに書き直しました。最近では、Object.keys()やString.prototype.startsWith()などの機能が標準で用意されています。なので、小さなライブラリを作成する程度であれば、依存関係を減らすためにも、Lodashなどを使わなくても良いかもしれません。
キー・ポイントでは、いろいろなライブラリを使いこなすエンジニアを募集しています。