6

I have a Material UI Textfield that contains an onChange. This onChange, takes the event and execute the function handleOnChange. With this current implementation, the function handleOnChange is executed every-time the event changes.

It it possible to use debounce to execute the function only after 2000ms directly on the event?

My textfield

<TextField
  onChange={
    event =>
      handleOnChange(
      event.target.value,
      firstValue,
      secondValue,                            
    )
/>

My function

const handleOnChange = (value, firstValue, secondValue) => {
  ...do something..
}

I tried the following, but handleOnChange still fires at every event change, not after 2000ms.

<TextField
  onChange={
    event =>
      _.debounce(handleOnChange(
      event.target.value,
      firstValue,
      secondValue,                            
    ), 2000)
/>
Gregor Albert
  • 819
  • 1
  • 11
  • 23
Magofoco
  • 5,098
  • 6
  • 35
  • 77
  • You could store the handleOnChange args in a singe state hook and debounce the state change, then whenever the debounced state changes, run a useEffect that calls handleOnChange with the debounces state value. – JMadelaine Jul 23 '20 at 11:54
  • Thanks! Could you please provide a code example? – Magofoco Jul 23 '20 at 12:11

2 Answers2

6

You are creating a debounced instance on every event call. Try creating one instance of debounced function and use it in your handler. Something like this:

const handleOnChange = _.debounce(change => {
  console.log(change);
}, 1000);

export default function App() {
  return (
    <div className="App">
      <input onChange={event => handleOnChange(event.target.value)} />
    </div>
  );
}
tjankowski
  • 148
  • 6
0

The issue is that you are passing the result of the handleOnChange() function to debounce, rather than a reference to the function.

Try something more like this:

<TextField
  onChange={
    event =>
      _.debounce(() => handleOnChange(
          event.target.value,
          firstValue,
          secondValue,                            
        ), 2000)
/>
  • I tried your suggestion but my `handleOnChange` does not fire at all – Magofoco Jul 23 '20 at 12:11
  • Apologies, I will have to have a bit more of a think about the structure of that call... perhaps it is meant to be more like `onChange=_.debounce(event => handleOnChange(...), 2000)`. If this doesn't work, I suggest posting a more complete example. – N. Brittain Jul 23 '20 at 12:15