如何在 Rect 鼠标按下时连续触发回调?

How do I trigger a callback continuously while mouse is down in Rect?

我一直在尝试实现一个简单的功能,该功能会在鼠标按下按钮时持续触发。我用一个组件的不同生命周期方法尝试了不同的解决方案,不幸的是它们都陷入了死循环。

我的方法是让 while 循环执行,除非不再按下按钮。将组件状态更新为 isPressed: false 的事件是 onMouseUponMouseLeave。快速示例:

...
componentWillUpdate() {
  while (this.state.isPressed) this.doSomething();
}

render() {
  <div
    onMouseDown={() => this.setState({ isPressed: true })}
    onMouseUp={() => this.setState({ isPressed: false })}
    onMouseLeave={() => this.setState({ isPressed: false })}
  >
   Hey
  </div>
}

我明白为什么这种方法不起作用,但我很难弄清楚如何以正确的方式实施它。

据我所知,你想在一个时间间隔内触发一些东西,所以简单地检查状态不是一个选项(这可能会更好,例如 this.state.isPressed ? doThis() : doThat())。您可以选择的一种方法是使用 Javascript 的 setInterval。这是一个简单的例子:

class Example extends React.Component {
  constructor() {
    super();
    this.down = this.down.bind(this);
    this.up = this.up.bind(this);
    this.interval = {};
  }
  down() {
    this.interval = setInterval(() => this.doSomething(), 100);
  }
  up() {
    clearInterval(this.interval);
  }
  doSomething() {
    console.log('Did something!');
  }
  render() {
    return (
      <div onMouseDown={this.down} onMouseUp={this.up} onMouseLeave={this.up}>
        Hey
      </div>
    );
  }
}

ReactDOM.render(<Example />, document.getElementById("View"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='View'></div>

https://codepen.io/anon/pen/peoLeN

class Application extends React.Component {
  constructor() {
    super();
    this.state = {
       timer: 0
    }
    this.pressed = false;

    this.doIt = this.doIt.bind(this);
  }
  down() {
   if(!this.pressed)  //Prevent multimple loops!
     this.pressed = setInterval(this.doIt, 100 /*execute every 100ms*/);
  }
  up() {
    if(this.pressed) {  //Only stop if exists
     clearInterval(this.pressed);
     this.pressed = false;
     this.setState({timer: 0});
   }
  }
  doIt() {
    this.setState({timer: this.state.timer+1});
  }
  render() {
    return <div>
      <button
    onMouseDown={() => this.down()}
    onMouseUp={() => this.up()}
  >
   {this.state.timer}
  </button>
    </div>;
  }
}

React.render(<Application />, document.getElementById('app'));