0

I have react app & need to trigger a function once user stops typing in the textbox. This is what I tried.

const inputHandler =(e:SynthenticEvent) => {
 let timer: any = null;
 clearTimeout(timer);
 
 timer = setTimeout(() => {
 console.log('hi');
 //in actual sending an Http request, however hiding it here for brevity
},1000);
}

<input type="text" onChange={inputHandler} name="userInput" />

What's happening as of now, that the inputHandler trigger after 1000ms but it trigger the multiples times (ex 100 is triggering 3 times, 1000 triggers 4 times)

Which is not ideal or expected?

I thought to make use of useEffect, but on doing so inputHandler() is not in identified/scope by textbox?

What I'm looking is at trigger the function after 1000ms but once with latest value of the texbox?

Thanks!

Kgn-web
  • 7,047
  • 24
  • 95
  • 161
  • `onChange` in react is actually mapped to the `input` event so typing `100` triggers your handler 3 times and sets three timers. You'll need to clarify when you want your timer set (probably when the input loses focus, or some other marker that the user is done typing). – pilchard Jun 21 '22 at 10:37
  • see: [How to start search only when user stops typing?](https://stackoverflow.com/questions/42217121/how-to-start-search-only-when-user-stops-typing) – pilchard Jun 21 '22 at 10:40

2 Answers2

1

This called debounce

Debounce function.

Javascript code.

function debounce(func, timeout = 300){
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => { func.apply(this, args); }, timeout);
  }
}

Typescript code.

function debounce<Params extends any[]>(func: Function, timeout = 
  300) {
  let timer: ReturnType<typeof setTimeout>;
  return (...args: Params) => {
    clearTimeout(timer);
    timer = setTimeout(() => { func.apply(this as Function, 
      args); }, timeout);
  }
}

To use it.

const handleChange = debounce(() => console.log('hi'))


<input type="text" onChange={inputHandler} name="userInput" />
Mina
  • 14,386
  • 3
  • 13
  • 26
0

Thanks to @Mina for letting me know about debouncing. On googling around debounce in javascript, I found a minor fix in my code which addressed my requirement precisely

I was almost close, all I was doing wrong was that I had defined & initialized the timer inside the function, just moving outside the target function resolved the issue

let timer: any = null; //moved outside the function
const inputHandler =(e:SynthenticEvent) => {
clearTimeout(timer);
timer = setTimeout(() => {
console.log('hi'); 
//in actual sending an Http request, however hiding it here for brevity
},1000);
}
Kgn-web
  • 7,047
  • 24
  • 95
  • 161