Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform debounce on onChange react event?

I have a problem in performing requests to the server when the user types some info in input field. Requests are sent but if the user quickly removes everything from the field, request won't be sent as default but it will send the last letter. So some delay happens.

I need to realize somehow debounce when the user types something quickly and send a request once for 2ms for example

<input type="text"
  placeholder="add"
  className='input'
  onChange={(e) => this.search(e.target.value)}
  onKeyDown={this.handleSearchParam}
  value={keyword}
/>

function for handling input

search(text) {
    this.props.onTextInputAdd(text);
    if (text) {
     this.props.onSearchTypeResult(this.props.tab, text)
    } else {
      this.props.onLoadDefaultInfo(this.props.tab);
    }
}

const mapStateToProps = state => ({
  keyword: state.searchReducers.keyword,
});

const mapDispatchToProps = dispatch => ({
  onSearchTypeResult: (tabName, query) => dispatch(actionCreators.loadSearchInfo(tab, tabQuery)),
  onTextInputAdd: keyword => dispatch(actionCreators.addKeyword(keyword)),
});

Here is the action:

const loadSearchResults = (tabName, query) => axios.get(`testurl?query1=${tabName}&query2=${query}`)

export const loadSearchInfo = (tabName, query) => dispatch => {
  loadSearchResults(tabName, query).then(response => {
    const data = { ...response.data };
    dispatch(updateTabInfo(data));
  });
}

export const updateTabInfo = data => ({
  type: LOAD_TAB_INFO,
  payload: data,
});

I tried to use custom debounce but it doesn't work. It fires every time I put text but not on intervals

like image 712
rick1 Avatar asked Sep 28 '18 18:09

rick1


1 Answers

You can use lodash debounce method like this:

search = _.debounce((text) => {
  this.props.onTextInputAdd(text);
  if (text) {
   this.props.onSearchTypeResult(this.props.tab, text)
  } else {
    this.props.onLoadDefaultInfo(this.props.tab);
  }
}, 300);

Then you will be able to use it like you already do. The function search will be triggered after 300ms. 2ms will probably be too fast.

<input type="text"
  placeholder="add"
  className='input'
  onChange={(e) => this.search(e.target.value)}
  onKeyDown={this.handleSearchParam}
  value={keyword}
/>

To use lodash, run npm install lodash --save or yarn add lodash then import it like this :

import _ from "lodash";

If you don't want to add lodash only for the debounce function, you can create your own debounce function like this:

function debounce(func, wait) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    const later = function() {
      timeout = null;
      func.apply(context, args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};
like image 67
Vincent D'amour Avatar answered Sep 20 '22 22:09

Vincent D'amour