[フロントエンド] React.jsで、クラスのメソッドのthisを一括でバインドする
こんにちは、@yoheiMuneです。
今日はReactで、onClickなどで呼び出す関数のthisを、一括でクラスにバインドする方法を、ブログに書きたいと思います。
親クラスでは
Handling Events - React
最後になりますが本ブログでは、フロントエンド、Swift、PHP、Node.js、Linux、Python、Java、インフラ、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時の、解決の糸口に!」そんな目標でブログを書き続けています。ぜひ、本ブログのRSSやTwitterをフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!
今日はReactで、onClickなどで呼び出す関数のthisを、一括でクラスにバインドする方法を、ブログに書きたいと思います。
目次
何が問題か
ReactコンポーネントをES6のクラスで作成すると、onClickで呼び出すメソッドのthis
がundefined
になってしまいます。import React, { Component } from 'react' class MyComponent extends Component { onClick() { console.log(this) // 「undefined」になる. } render() { return ( <div onClick={this.onClick}>Click Me!!</div> ); } }対処法としては以下のようにthisをバインドすれば良いのですが、毎回やるのは面倒です。
<div onClick={this.onClick.bind(this)}>Click Me!!</div>それを、一括でやってしまおうというのが今回の内容です。
共通の親クラスを作成して、thisのバインドを行う
プロジェクト全体で利用する共通のベースコンポーネントを作成し、その中でthisのバインド処理を行います。各コンポーネントはこの親クラスを継承して作るようにすることで、thisのバインドを自動的に行います。親クラスでは
constructor
の中で、自分自身の全てのメソッドについてthis
のバインドを行います。import { Component } from 'react' /** * React.Componentの基底クラス. */ export default class AbstractComponent extends Component { constructor() { super(...arguments) this.autoBind() } // 自身のメソッドについて「this」のバインドを行う autoBind() { Object.getOwnPropertyNames(this.constructor.prototype) .filter(prop => typeof this[prop] === 'function') .forEach(method => { this[method] = this[method].bind(this); }); } }そして、上記のクラスを継承して、各コンポーネントを作成します。
import React from 'react' import AbstractComponent from './AbstractComponent' class MyComponent extends AbstractComponent { // <== 継承先を変更 onClick() { console.log(this) // MyComponentのインスタンスになってる!! } render() { return ( <div onClick={this.onClick}>Click Me!!</div> ); } }これで自動的にthisのバインドができました。
参考資料
onClickにおけるthis
の扱いは、今回紹介した方法以外にもいくつか存在します。以下の公式ドキュメントをご参照ください。Handling Events - React
最後に
僕は今回のやり方がしっくりきていますが、他にも色々と良い方法があるので、自分にあった(プロジェクトに合った)方法を選べるといいなと思います 。最後になりますが本ブログでは、フロントエンド、Swift、PHP、Node.js、Linux、Python、Java、インフラ、Go言語、機械学習、などの技術トピックを発信をしていきます。「プログラミングで困ったその時の、解決の糸口に!」そんな目標でブログを書き続けています。ぜひ、本ブログのRSSやTwitterをフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!