Rate Limiting

If you have an event handler such as onInput, onMove or onScroll and want to prevent the callback from being fired too many times in a row, then you can limit the rate at which callback is executed. There are three ways to do this:

throttling: sample changes based on a time-based frequency


RESETRUNFULL
import throttle from 'lodash.throttle';class LoadMoreButton extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);this.handleClickThrottled =
                                    throttle(this.handleClick, 1000); // max 1 time/sec
  }
  componentWillUnmount() {
    this.handleClickThrottled.cancel();
  }
  render() {
    return <button onClick={this.handleClickThrottled}>Load More</button>;
  }
  handleClick() {
    this.props.loadMore();
  }}

debouncing: publish changes after a period of inactivity


RESETRUNFULL
import debounce from 'lodash.debounce';class Searchbox extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);this.emitChangeDebounced =
            debounce(this.emitChange, 250);   // wait 250ms before next input
  }
  componentWillUnmount() {
    this.emitChangeDebounced.cancel();
  }
  render() {
    return (
      <input
        type="text"
        onChange={this.handleChange}
        placeholder="Search..."
        defaultValue={this.props.value}
      />
    );
  }
  handleChange(e) {
    this.emitChangeDebounced(e.target.value);
  }
  emitChange(value) {
    this.props.onChange(value);
  }}

requestAnimationFrame throttling: sample changes based on requestAnimationFrame


RESETRUNFULL
import rafSchedule from 'raf-schd';class ScrollListener extends React.Component {
  constructor(props) {
    super(props);
    this.handleScroll = this.handleScroll.bind(this);    // Create a new function to schedule updates.
    this.scheduleUpdate = rafSchedule(
      point => this.props.onScroll(point)
    );
  }
  handleScroll(e) {    // When we receive a scroll event, schedule an update.    // If we receive many updates within a frame, we'll only publish the latest value.
    this.scheduleUpdate({ x: e.clientX, y: e.clientY });   // queue a call
  }
  componentWillUnmount() {    // Cancel any pending updates since we're unmounting.
    this.scheduleUpdate.cancel();
  }
  render() {
    return (
      <div style={{ overflow: 'scroll' }}
  onScroll={this.handleScroll}>
        <img src="/my-huge-image.jpg" />
      </div>
    );
  }}