Skip to content

Instantly share code, notes, and snippets.

@adyontech
Last active January 15, 2020 05:16
Show Gist options
  • Save adyontech/807aa749d070f6bb847f4887a72ecf00 to your computer and use it in GitHub Desktop.
Save adyontech/807aa749d070f6bb847f4887a72ecf00 to your computer and use it in GitHub Desktop.
Input throttling with react

Correct implementation:-

import React from "react";

const throttle = (callback, limit) => {
  var wait = false;

  return function(...arg) {
    if (!wait) {
      console.log("updating");
      callback.call(this, ...arg);
      wait = true;
      setTimeout(function() {
        wait = false;
      }, limit);
    }
  };
};

const otherFun = e => {
  console.log(e.target.value);
};

export default class App extends React.Component {
  throttled = throttle(otherFun, 2000);
  onInput = e => {
    e.persist();
    this.throttled(e);
  };

  render() {
    return (
      <>
        <input onChange={this.onInput} />
      </>
    );
  }
}

Wrong implementation

import React from "react";

const throttle = (callback, limit) => {
  var wait = false;

  return function() {
    if (!wait) {
      console.log("updating");
      callback.call();
      wait = true;
      setTimeout(function() {
        wait = false;
      }, limit);
    }
  };
};

const otherFun = e => {
  console.log(e.target.value);
};

export default class App extends React.Component {
  onInput(e) {
    throttle(otherFun, 2000);
  }

  render() {
    return (
      <>
        <input onChange={this.onInput} />
      </>
    );
  }
}

Understanding on changed implementation.

onInput(e) {
   throttle(otherFun, 2000);
 }

This does not call the function otherFun but creates a "new version" of the function. And doing it like I did would create it on each input, that's why I created it as a class variable:

export default class App extends React.Component {
 throttled = throttle(otherFun, 2000);

and then call it this.throttled(e);

I also needed to add e.persist(); due to how the SyntheticEvents work in React. Also, the throttled implementation I created:

return function() {
   if (!wait) {
     console.log("updating");
     callback.call();
     wait = true;
     setTimeout(function() {
       wait = false;
     }, limit);
   }
 };

returns a copy of the function that does not expect any arguments. so new changes:

return function(...arg) {
// and
callback.call(this, ...arg);

added supports for an arbitrary number of arguments .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment