Skip to content
Sandny Blog
  • Home
  • Java
  • JavaScript
  • AWS
  • Embedded
  • About
Debounce and avoid multiple clicks JavaScript

Debounce and avoid multiple clicks event generation on React.js…

  • November 1, 2017August 26, 2018
  • by Coder Kai

There are some instances where you need to debounce and avoid multiple clicks/taps on a button so that it will not generate the same action chain immediately with a consecutive click. An example would be an application with a touchscreen. If you click a button rapidly, that event will be generated more than once. As a solution, most of the time devs would block the UI until the action chain is completed. But this would be a bad experience if the user is blocked for any other interactions. A typical example can be a fetch call to update the state and if the invocation is asynchronous it could be causing more inconvenience.

How to debounce and avoid multiple clicks

What I did was to create a stateful component with react.js and use debounce function of Lodash(https://lodash.com/docs/4.17.4#debounce). This will debounce and avoid multiple clicks which are generated after the first click/tap for a limited time. With leading: true, it will define that the first click will be executed all the trailing invocations are discarded.

I created a ClickableComponent class which could be used for any component with an onClick parameter.

class ClickableElement extends React.Component {
  static INTERVAL = 1000;

  constructor(props) {
    super(props);
    this.state = {};
  }

  componentWillReceiveProps(nextProps) {
    const { onClick, disabled } = nextProps;
    this.setState({
      onClick,
      disabled,
    });
  }

  onClickDebounced(e) {
    const { onClick, disabled } = this.state;
    if (!disabled && _.isFunction(onClick)) {
      onClick(e);
    }
  }

  componentWillMount() {
    this.componentWillReceiveProps(this.props);
    const { clickWait } = this.props;
    const wait = clickWait || Button.INTERVAL;
    this.onElementClicked = _.debounce(this.onClickDebounced,
       wait,
      {
        maxWait:wait,
        leading: true,
        trailing: false,
      });
  }
}

 

Note that I have used Lodash as _ in the code. Now you can use it in any component where you would invoke onClick  function.

export class TouchButton extends ClickableElement {
  render() {
    const otherProps = _.omit(this.props, ['onClick', 'type']);
    return (
      <button
          onClick={e => this.onElementClicked(e)}
          type="button"
          {...otherProps}
      >{otherProps.value}</button>
    );
  }
}

See the Pen React Debounce Button by Sandaruwan Nanayakkara (@sandaruny) on CodePen.

Finally the click debouncing time is in milliseconds and default wait time of one second has set with INTERVAL static property. And if you want to override the waiting time for the clicks, you can set the wait time as desired.

<TouchButton
    clickWait={2000}
    onClick={() => doSomething()}
    value="Something"
/>

This is working great and if you want to generate an event for once, you can slightly modify the Lodash debounce function parameters.
If you have simpler approach please do give a feedback.

babel + express.js + node.js + nodemon to build API with hot reloading
A Modular Approach to create API using Express.js and Node.js
Coder Kai
A humble developer
avoid multiple invocations debounce debounce click es2016 es6 lodash multi taps multiple events onClick react.js redux.js

Related articles

Multiple refs for an array of React Elements
Using multiple refs for an…
Immutable and Mutable Values in Javascript
07. Immutable and Mutable Values…
wrapper objects in javascript
06. Wrapper objects in Javascript
globals undefined and null values in javascript
05 Global, null and undefined…
Javascript Booleans and Equality
04. Javascript Guide Booleans and…
How to add Chakra UI Animations
Chakra UI Animations
SSL Websocket using Nginx Proxy
SSL Websocket proxy with Nginx…
Change python version correctly
Python is not setting correct…
optimize React.js load time
How to optimize React.js app…
Multiple refs for an array of React Elements
How to use IntersectionObserver to…
Multiple refs for an array of React Elements
How to dismiss dropdowns when…
Javascript guide Strings
03. Javascript Guide – Strings
How to fetch data with useEffect
How to fetch data with…
add styles to stripe elements
How to add styles to…
Typescript
How to use Typescript with…
how to optimize react-native map view
How to optimize react-native map…
debounce with react hooks
Avoid multiple clicks using debounce…
Numbers inJavascript
02. Javascript Guide – Numbers
Introduction to Javascript
01. Javascript Guide – Introduction…
Nginx Load Balancer with docker…

Categories

  • android 3
  • Apollo Client 1
  • AWS 8
    • AppSync 5
    • EC2 1
    • EKS 1
    • Route53 1
    • S3 1
  • AWS Amplify 1
  • Chakra UI 1
  • Docker 1
  • Embedded 1
  • EmberJS 1
  • FCM 1
  • Godaddy 1
  • GraphQL 3
  • ios 1
  • Jasper 1
  • Java 10
    • Java 11 1
    • Java 14 1
  • JavaEE 2
  • JavaScript 39
    • Express.js 4
    • Javascript Guide 7
    • Node.js 3
    • react-native 4
    • React.js 17
    • Typescript 1
  • Kubernetes 1
  • machine learning 1
  • Maven 2
  • OCaml 3
  • PostgreSQL 1
  • Python 2
  • react-native 4
  • ReactJS 3
  • sass 1
  • Server 6
  • spark 1
  • Terraform 2
  • Ubuntu 4
  • Uncategorized 1
  • webpack 2

Recent Comments

  • prediksi sgp hari ini on Android/iOS React-native heap limit allocation failed error
  • baho naziile on How to optimize React.js app load time using react lazy
  • bexshii pollayn on How to create a neo4j BoltDriver Datasource and connect it with a web app

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

Archives

  • October 2022 3
  • September 2022 7
  • May 2022 1
  • December 2021 1
  • August 2021 1
  • July 2021 6
  • June 2021 3
  • February 2021 1
  • July 2020 1
  • December 2019 5
  • November 2019 6
  • October 2019 3
  • August 2019 1
  • March 2019 1
  • February 2019 1
  • January 2019 2
  • December 2018 1
  • September 2018 2
  • August 2018 1
  • June 2018 1
  • February 2018 1
  • November 2017 2
  • October 2017 5
  • September 2017 1
  • June 2017 1
  • May 2017 10
Sandny Blog space
Theme by Colorlib Powered by WordPress