Create button effect pressed

Asked

Viewed 620 times

1

I have the following component in React:

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: parseInt(this.props.value)
    };

    this.inc = this.inc.bind(this);
    this.dec = this.dec.bind(this);
  }

  inc() {
    this.setState({ count: this.state.count + 1 });
  }

  dec() {
    this.setState({ count: this.state.count - 1 });
  }

  render() {
    return (
      <div>
        <p>
          O valor inicial é: <code>{this.props.value}</code>.
        </p>
        <div>
          O valor <strong>atual</strong> é: <code>{this.state.count}</code>.
        </div>
        <div>
          <button onClick={this.inc}>Incrementar</button>
          <button onClick={this.dec}>Decrementar</button>
        </div>
      </div>
    );
  }
}

module.exports = Counter;

It basically has a number, which, when pressing a button, is incremented in one. Thus, at each click, the value increases a.

How do I, by holding down this button (holding down the left mouse button), continue to increase the value (until I stop pressing the left button)?

1 answer

3


Define within the constructor method a variable, example:

this.interval = null;

She’ll save the timer setInterval, now create a method to clean the timer:

clear() {
    clearInterval(this.interval);
    this.interval = null;
}

In the constructor method bind the new method:

this.clear = this.clear.bind(this);

It shall make the following modifications to the methods inc and dec:

inc() {
    if (this.interval === null) {
        this.interval = setInterval(this.inc, 100);
    }
    this.setState({ count: this.state.count + 1 });
}

dec() {
    if (this.interval === null) {
        this.interval = setInterval(this.dec, 100);
    }
    if (this.state.count > 0) {
        this.setState({ count: this.state.count - 1 });
    }
}

Change the events onClick for onMouseDown and add the event onMouseUp who will execute the method clear, thus leaving the code:

<button onMouseUp={this.clear} onMouseDown={this.inc}>Incrementar</button>
<button onMouseUp={this.clear} onMouseDown={this.dec}>Decrementar</button>

Working example

class Counter extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      count: parseInt(this.props.value)
    };
    this.interval = null;
    this.clear = this.clear.bind(this);
    this.inc = this.inc.bind(this);
    this.dec = this.dec.bind(this);
  }

  inc() {
    if (this.interval === null) {
      this.interval = setInterval(this.inc, 100);
    }
    this.setState({ count: this.state.count + 1 });
  }

  dec() {
    if (this.interval === null) {
      this.interval = setInterval(this.dec, 100);
    }
    if (this.state.count > 0) {
      this.setState({ count: this.state.count - 1 });
    }
  }

  clear() {
    clearInterval(this.interval);
    this.interval = null;
  }

  render() {
    return (
      <div>
        <p>
          O valor inicial é: <code>{this.props.value}</code>.
        </p>
        <div>
          O valor <strong>atual</strong> é: <code>{this.state.count}</code>.
        </div>
        <div>
          <button className="inc" onMouseUp={this.clear} onMouseDown={this.inc}>Incrementar</button>
          <button className="dec" onMouseUp={this.clear} onMouseDown={this.dec}>Decrementar</button>
        </div>
      </div>
    );
  }
}


ReactDOM.render(<Counter value="0" />, document.getElementById('app'));
button {
  border: 0;
  color: #fff;
  cursor: pointer;
  font-family: 'Verdana', sans-serif;
  font-size: 1em;
  padding: 8px;
  text-transform: uppercase;
}

.inc {
  background: #388E3C;
  margin-right: 14px;
}
.dec {
  background: #E57373;
}
<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="app"></div>

If you prefer you can see running on codesandbox.io

Reference

  • Thanks for the help.

  • Very nice. That’s it.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.