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

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…
dismiss dropdowns when pressed on background with React.js
How to use IntersectionObserver to…
dismiss dropdowns when pressed on background with React.js
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…
Create React App Using npx
Difference Between npx and npm
Simple Tab View Using react-tabs
Use Dynamic Segments Routing in Ember 2.0
The Common Errors that beginner…
FCM Push Notification with React Native
How to setup FCM Push…
Frequent errors with Apollo Client
Query definition in GraphQL and…

Categories

  • android 3
  • Apollo Client 1
  • AWS 7
    • AppSync 5
    • EC2 1
    • EKS 1
    • Route53 1
  • AWS Amplify 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 32
    • Express.js 4
    • Javascript Guide 3
    • Node.js 1
    • react-native 4
    • React.js 15
    • Typescript 1
  • Kubernetes 1
  • machine learning 1
  • Maven 2
  • OCaml 3
  • react-native 4
  • ReactJS 3
  • sass 1
  • Server 6
  • spark 1
  • Ubuntu 4
  • Uncategorized 1
  • webpack 2

Recent Comments

  • ChesterCurdy on Create React App Using npx
  • RitaNasy555 on Difference Between npx and npm
  • megaword on The Common Errors that beginner React Developers Make

Meta

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

Archives

  • 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