15

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

Matt C
  • 4,470
  • 5
  • 26
  • 44
rick1
  • 946
  • 3
  • 15
  • 31
  • 2
    Possible duplicate of [Perform debounce in React.js](https://stackoverflow.com/questions/23123138/perform-debounce-in-react-js) – mhatch Sep 28 '18 at 19:05
  • no it isn't, I checked those but it doesn't the case I have – rick1 Sep 28 '18 at 19:07
  • 1
    You need to create a debounce method on the component instance, then call that method from the onchange. The instance method will make your api call. It is the same. – mhatch Sep 28 '18 at 19:24
  • so provide me with instruction to my case please. I do not have any idea how to do that using the link you send me. It is the easiest way to send some link and close theme – rick1 Sep 28 '18 at 19:26
  • I provided you with all the code I write – rick1 Sep 28 '18 at 19:26

1 Answers1

27

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);
  };
};
Vincent D'amour
  • 3,746
  • 1
  • 27
  • 39