[フロントエンド] 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をフォローして貰えたら嬉しいです ^ ^
最後までご覧頂きましてありがとうございました!






