Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React on key up execute setTimeout only once

I need to run something when the user finishes typing, when the timer finishes basically. Timer is being reset when user is typing but once time is over, it will run the function for as many times as the user typed

export default function SearchMovie() {
    var keyUpTimer = 0;
    const keyUpTimerDelay = 2000;


    const handleOnKeyUp = (event) => {
        clearTimeout(keyUpTimer);
        keyUpTimer = setTimeout(() => {
    
            console.log(input);
        }, keyUpTimerDelay);
    };


    return (
        <div className="search-container">
            <input
                type="text"
                className="input-text"
                onInput={(e) => setInput(e.target.value)}
                onKeyUp={handleOnKeyUp}
                placeholder="Type a movie to search..."
            />
        </div>
    );
}
like image 320
Jackal Avatar asked Aug 07 '26 11:08

Jackal


1 Answers

Because React will call your function every render, every time your component renders, a new keyUpTimer variable with the value of 0 is created, so you are never really clearing the old timer. In order to maintain the same timer variable for every render, you should use a Ref.

import React, {useRef} from 'react';

export default function SearchMovie() {
    var keyUpTimer = useRef(null); // keyUpTimer will be a Ref object
    const keyUpTimerDelay = 2000;


    const handleOnKeyUp = (event) => {
        clearTimeout(keyUpTimer.current); // use `current` to access the value
        // the `current` property is mutable and changing it will not cause a rerender
        keyUpTimer.current = setTimeout(() => {
    
            console.log(input);
        }, keyUpTimerDelay);
    };


    return (
        <div className="search-container">
            <input
                type="text"
                className="input-text"
                onInput={(e) => setInput(e.target.value)}
                onKeyUp={handleOnKeyUp}
                placeholder="Type a movie to search..."
            />
        </div>
    );
}
like image 161
shamsup Avatar answered Aug 09 '26 00:08

shamsup