自己紹介
じゅんじゅんというニックネームで、関西を拠点に活動しているフロントエンドエンジニアです。
HAL大阪の2回生です👍 (2016.9.12現在)
よくstart up系イベントに行くので、大阪らへんの方は会いましょう!
bind問題とは
ReactをES6で書いた場合に、イベントハンドラでthisがundefinedとなりメソッドが実行できないという問題。
これはFacebookのReact公式にも書いていて
このリンクの中盤すぎぐらいに__ES6 Classes__と書いている欄。
___No Autobinding___と書いている。明示的にthisをバインドしてね!ってことらしいぞと。
ということで、解決策を具体的に書いていきたいと思います。
解決策たち
解決策的には
- constructor内に明示的にbind
- es6のアローファンクションを使う
- jsxコンポーネント内でbind
- stage-0でメソッドの定義をする
- 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
にも記述しましょう
{
"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
にも記述しましょう
{
"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