(JSX) メソッド内でthisを正しく参照する
React.Component
のメソッドを使う際にthis
が正しく参照できないことがあった。その原因と対処法を記す。動かせるコードはこちら。
問題
Click Me!
という文字列をクリックした時にThanks
と文字列が切り替わるようなコンポーネントを実装したい。
ここで次のようなコードにすると、クリックしても文字が切り替わらない。
class Clickable extends React.Component {
constructor(props) {
super(props);
this.state = { msg: "Click Me!"};
};
render () {
return <h1 onClick={this.handleClick}>{ this.state.msg }</h1>;
};
handleClick () { this.setState({ msg: "Thanks!"}); };
}
ReactDOM.render(
<Clickable/>,
document.getElementById('mount')
);
原因はメソッドhandleClick
を定義した時に、this
のスコープがメソッド内のものに置き換わってしまい、クラス内のスコープのthis
を参照することが出来ないためだ。
正しく動作させるための対処法を以下に書いていく。
対処法①:コンストラクタで束縛する
最初の対処法はクラスのコンストラクタ内でクラスのスコープでのthis
をメソッドに束縛させる方法だ。
class Clickable extends React.Component {
constructor(props) {
super(props);
this.state = { msg: "Click Me!"};
// 対処法① コンストラクタ内でhandleClickを束縛する
this.handleClick = this.handleClick.bind(this);
};
...
}
この方法はうまくいくが、束縛はコンストラクタ内で行う必要があるため、コンストラクタを省略することが出来なくなるという欠点がある。
対処法②:クロージャを使う
2番目の対処法はメソッド呼び出しの時にクロージャを使うことだ。render
が実行された時、クロージャによってクラスのthis
が束縛されるので、メソッド内で正しく参照を行うことが出来るようになる。
render () {
return <h1 onClick={() => this.handleClick()}>{ this.state.msg }</h1>;
};
この書き方ではコンストラクタ内で束縛する必要がなくなるため、コンストラクタが不必要な場合は省略することが出来る。
対処方③:アロー関数を使う
最後の対処法はメソッドhandlwClick
の定義にアロー関数表記を使うことだ。アロー関数は変数のリスコープを行わないので、元々のthis
をメソッド内部でそのまま参照することが出来る。JavaScriptでは関数は第1級のオブジェクトであるため、アロー関数をクラスのメンバ変数として登録している形となっている。
handleClick = () => { this.setState({ msg: "Thanks!"}); };
この書き方でもコンストラクタ内で束縛を行う必要はないので、コードが短くなる。
まとめ
メソッド内でクラスのthis
を参照する方法を3つ紹介した。
どうもJSのスコープは奥が深いというかクセがある。。
Author And Source
この問題について((JSX) メソッド内でthisを正しく参照する), 我々は、より多くの情報をここで見つけました https://qiita.com/shimaokasonse/items/2c582c5c5ef7f3629332著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .