1. ホーム
  2. javascript

[解決済み] ReactコンポーネントでonClickは動作するがonDoubleClickは無視される。

2023-03-25 07:33:53

質問

Reactでマインスイーパのゲームを作っているのですが、セルがシングルまたはダブルクリックされたときに別のアクションを実行したいのです。 現在 onDoubleClick 関数は決して起動しません。 onClick が表示されます。 もし私が onClick ハンドラを onDoubleClick が動作します。 なぜ両方のイベントが動作しないのでしょうか? 1つの要素で両方のイベントを持つことは可能ですか?

/** @jsx React.DOM */

var Mine = React.createClass({
  render: function(){
    return (
      <div className="mineBox" id={this.props.id} onDoubleClick={this.props.onDoubleClick} onClick={this.props.onClick}></div>
    )
  }
});

var MineRow = React.createClass({
  render: function(){
    var width = this.props.width,
        row = [];
    for (var i = 0; i < width; i++){
      row.push(<Mine id={String(this.props.row + i)} boxClass={this.props.boxClass} onDoubleClick={this.props.onDoubleClick} onClick={this.props.onClick}/>)
    }
    return (
      <div>{row}</div>
    )
  }
})

var MineSweeper = React.createClass({
  handleDoubleClick: function(){
    alert('Double Clicked');
  },
  handleClick: function(){
    alert('Single Clicked');
  },
  render: function(){
    var height = this.props.height,
        table = [];
    for (var i = 0; i < height; i++){
      table.push(<MineRow width={this.props.width} row={String.fromCharCode(97 + i)} onDoubleClick={this.handleDoubleClick} onClick={this.handleClick}/>)
    }
    return (
      <div>{table}</div>
    )
  }
})

var bombs = ['a0', 'b1', 'c2'];
React.renderComponent(<MineSweeper height={5} width={5} bombs={bombs}/>, document.getElementById('content'));

どのように解決するのですか?

編集してください。

React 0.15.3では問題ないことがわかりました。



オリジナルです。

React 0.13.3の場合、以下の2つの解決策があります。

1.参照コールバック

ダブルクリックの場合でも、シングルクリックハンドラは2回(各クリックに1回)呼ばれることに注意してください。

const ListItem = React.createClass({

  handleClick() {
    console.log('single click');
  },

  handleDoubleClick() {
    console.log('double click');
  },

  refCallback(item) {
    if (item) {
      item.getDOMNode().ondblclick = this.handleDoubleClick;
    }
  },

  render() {
    return (
      <div onClick={this.handleClick}
           ref={this.refCallback}>
      </div>
    );
  }
});

module.exports = ListItem;

2. ロダッシュデバウンス

私は別の解決策として lodash を使用する別のソリューションがありましたが、複雑なため断念しました。この利点は、"click" が 1 回だけ呼び出されること、そして "double-click" の場合にはまったく呼び出されないことでした。

import _ from 'lodash'

const ListItem = React.createClass({

  handleClick(e) {
    if (!this._delayedClick) {
      this._delayedClick = _.debounce(this.doClick, 500);
    }
    if (this.clickedOnce) {
      this._delayedClick.cancel();
      this.clickedOnce = false;
      console.log('double click');
    } else {
      this._delayedClick(e);
      this.clickedOnce = true;
    }
  },

  doClick(e) {
    this.clickedOnce = undefined;
    console.log('single click');
  },

  render() {
    return (
      <div onClick={this.handleClick}>
      </div>
    );
  }
});

module.exports = ListItem;

石鹸箱の上で

ダブルクリックは簡単に検出できるものではないという考え方はありがたいのですが、良くも悪くもそれは IS

というパラダイムが存在し、オペレーティング システムで普及しているため、ユーザーはそれを理解します。さらに、これは、最新のブラウザがまだサポートしているパラダイムです。DOM の仕様から削除されるまでは、React は機能する onDoubleClick プロップと並んで onClick . そうでないようなのは残念です。