Reactでシングルクリックとダブルクリックを区別して使いたい

先に今回の話のソースコードです。 github.com

Reactでは シングルクリックイベントとダブルクリックイベントが用意されています。

シングルクリック

<a href="javascript:void(0)"
   onClick={(e) => this.handleOnSingleClick(e)}>
   Single Click
</a>

onClickイベントが用意されています。

ダブルクリック

<a href="javascript:void(0)"
   onDoubleClick={(e) => this.handleOnDoubleClick(e)}>
   Double Click
</a>

onDoubleClickイベントが用意されています。
※ mobile safari だと動きませんでした。

それぞれを別々に使う分には期待した通りに動作します。

問題はSingleClickとDoubleClickを両方設定したときです。

<a href="javascript:void(0)"
   onClick={(e) => this.handleOnSingleClick(e)}
   onDoubleClick={(e) => this.handleOnDoubleClick(e)}>
   Single Click and Double Click
</a>

こんな形で実装して、ダブルクリックしてみると、onClickイベントが2回とonDoubleClickイベントが1回発火します。
シングルクリックのときは onClickイベントだけ、ダブルクリックの時はonDoubleClickイベントだけと区別して使いたいことがあります。

そういったときどうするのかという話です。

ソースコードはTypescriptで書いてます。

import * as React from 'react';

interface IAppProps {
}
interface IAppState {
}

export class App extends React.Component<IAppProps, IAppState> {

  private clickCount: number;

  constructor(props: IAppProps) {
    super(props);

    this.clickCount = 0;

    this.state= {};
  }

  /**
   * Single or Double Click
   */
  handleOnSingleOrDoubleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
    this.clickCount++;

    if (this.clickCount < 2) {
      setTimeout(() => {
        if (this.clickCount > 1) {
          console.log('Double Click');
        } else {
          console.log('Single Click');
        }
        this.clickCount = 0;
      }, 200);
    }
  }

  render() {
    return (
      <div>
        <a href="javascript:void(0)"
          onClick={(e) => this.handleOnSingleOrDoubleClick(e)}>
          Single Click or Double Click
        </a>
      </div>
    );
  }
}

の様に書くとシングルクリックとダブルクリックを区別することができます。

キモになるのはこの部分で、onClickイベントのみを使います。

  /**
   * Single or Double Click
   */
  handleOnSingleOrDoubleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
    this.clickCount++;

    if (this.clickCount < 2) {
      setTimeout(() => {
        if (this.clickCount > 1) {
          console.log('Double Click');
        } else {
          console.log('Single Click');
        }
        this.clickCount = 0;
      }, 200);
    }
  }

クリックイベント時に、クリック数をインクリメントして、setTimeoutで後からクリック後の動作を実行してあげることでシングルクリックとダブルクリックを別々に認識させることができます。

クリックして動作が見れるページを作ってみたので、興味がある人はクリックしてみて下さい。 React doubleclick sample