2
1

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 1 year has passed since last update.

[TypeScript]イベントリスナー内のthisの参照問題を解決![bind]

Posted at

イベントリスナー内のthisの参照問題

TypeScriptでクラスメソッドをイベントリスナーとして使用する際に、thisの参照が期待通りにならない問題が発生することがあります。
これを解決する方法として、bindメソッドを使用するという方法があります。
今回は、この問題の発生原因とbindを使った解決法について、実際のコードを元に紹介します!

1. 問題の発生

イベントリスナー内でクラスメソッドを呼び出すと、thisの参照が予期せず上書きされ、意図しない挙動を引き起こすことがあります。
例えば、以下のコードように、生成したボタンへ押下時に「Click me!」を表示させるメソッドをイベントリスナーにて設定しようとしたときに、問題が発生します。

class MyButton {
  private buttonText: string;

  constructor(buttonText: string) {
    this.buttonText = buttonText;
    this.setupButton();
  }

  private setupButton() {
    const button = document.createElement('button');
    button.innerText = this.buttonText;
    button.addEventListener('click', this.handleClick);
    document.body.appendChild(button);
  }

  private handleClick() {
    // 'this'の参照が 'MyButton' インスタンスではなく、
    // イベントが発生した 'button' 要素になってしまう
    console.log(this.buttonText);
  }
}

const myButton = new MyButton('Click me!');

ボタンを押下した時、イベントリスナーにて、handleClickメソッドが呼び出されるのですが、その際、this.buttonTextにアクセスします。
しかし、実際でのthisの参照がbutton要素になってしまい、button要素には勿論buttonTextプロパティなどなくundefinedとなってしまい、想定と異なる挙動になってしまいます!

2. 解決

この問題を解決するために、bindメソッドを使ってイベントリスナー内でのthisの参照を正しく設定できます!

class MyButton {
  // ...

  private setupButton() {
    const button = document.createElement('button');
    button.innerText = this.buttonText;

    // bindメソッドを使って、handleClickメソッド内の'this'を'MyButton'インスタンスに固定する
    button.addEventListener('click', this.handleClick.bind(this));

    document.body.appendChild(button);
  }

  private handleClick() {
    // 'this'は'MyButton'インスタンスを指す
    console.log(this.buttonText);
  }
}

このようにbindメソッドを使用することで、handleClickメソッド内でのthisの参照を正しく設定できます!

まとめ

thisの参照の問題はよく発生してしまうので、どこを参照してしまうのかを意識してコードを書いていきましょう!

次回は、このbindメソッドをもっと再利用できるように、デコレータを使ってのbindメソッドの使用例を紹介します!

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?