57
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactをES6で開発時のbindの問題

Last updated at Posted at 2016-09-12

自己紹介

じゅんじゅんというニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。

HAL大阪の2回生です👍 (2016.9.12現在)

よくstart up系イベントに行くので、大阪らへんの方は会いましょう!

bind問題とは

ReactをES6で書いた場合に、イベントハンドラでthisがundefinedとなりメソッドが実行できないという問題。

これはFacebookのReact公式にも書いていて

Reusable Components

このリンクの中盤すぎぐらいに__ES6 Classes__と書いている欄。

___No Autobinding___と書いている。明示的にthisをバインドしてね!ってことらしいぞと。

ということで、解決策を具体的に書いていきたいと思います。

解決策たち

解決策的には

  1. constructor内に明示的にbind
  2. es6のアローファンクションを使う
  3. jsxコンポーネント内でbind
  4. stage-0でメソッドの定義をする
  5. es7のbindオペレータを使う

前半3つはすぐに導入することができますが、後半2つを使うには少しプラグインなどを入れる必要があります。

1. constructor内に明示的にbind

constructor(){
  super()
  this._hoge = this._hoge.bind(this);
}

_hoge(){
  console.log("hoge");
}

この方法は、メソッドが多くなるにつれてthis祭りになるので、推奨はしないですが楽です()

2. es6のアローファンクションを使う

render(){
  return(
    <button onClick={(e)=>this._click(e)}>click me</button>
  )
}

_click(){
  console.log("click!")
}

この方法は、eventを渡す必要があるようなので(e)=>this._click(e)と書いています。

3. jsxコンポーネント内でbind

render(){
  return(
    <button onClick={this._click.bind(this)}>click me</button>
  )
}

_click(){
  console.log("click!")
}

これは、コンストラクタでthisのbindをしていない分jsxの方で書いとくぜ!って感じなんですかね。

4. stage-0でメソッドの定義をする

まず、この開発環境でstage-0が使えるようにしないといけません。

npm install babel-preset-stage-0

.babelrcにも記述しましょう

.babelrc
{
  "presets": ["react", "es2015","stage-0"]
}

メソッドの書き方を変えましょう。

render(){
  return(
    <button onClick={this._click}>click me</button>
  )
}

_click = () => {
  console.log("click!")
}

5. es7のbindオペレータを使う

es7のbindオペレータを扱うためにbabelにプラグインとして

transform function bindを使います。

npm install babel-plugin-transform-function-bind

.babelrcにも記述しましょう

.babelrc
{
  "presets": ["react", "es2015"],
  "plugins": ["transform-function-bind"]
}

jsx内のthis._clickを書き換えます

render(){
  return(
    <button onClick={::this._click}>click me</button>
  )
}

_click(){
  console.log("click!")
}

この5つの方法以外の方法に、ReactのComponentを継承して自分でMyComponent見たいなものを作り、そのMYComponentのコンストラクタで_から始まるメソッドは全部thisでバインドする。みたいな書き方ができそう!って感じですが、今回はこの5つの方法で記事をまとめておきます。

最後に

個人的にReactをとても活用していて、最近やっとReactNativeを触り始めました。。

すごいですね...w

Googleのトレンド的にはAngular2とかがトレンドらしいので、また時間があれば噛んでみようかなと思ってます!

Twitter @konojunya

57
54
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
57
54

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?