Axel
Axel

Reputation: 207

Run function in useeffect when state changes after 1 second if no other changes

I am trying to create a searchbar that sends request to my server to give results as the user is writing. It seems a bit impractical to send a request as soon as a user writes if he/she writes quickly, so I would like to make the function in the useEffect hook taking care of this run after 1 second if there has been no input, and reset that timer everytime the user inputs something.

The code works like this at the moment, but I would like to add the functionality described above, but I don't really know how to go about to do that. Does anyone have a solution to this?

 React.useEffect(() => {
      if (input.length > 1) {

        (async () => {
          try {
            setLoading(true);
            const res = await axiosget<Searchresult[]>(
              `search/input=${input}`
            );

            setSearchresults(res);
          } catch {
            setSearchResults([]);
          }
          setLoading(false);
        })();
      } else {
        setSearchResults([]);
      }

  }, [input]);

Thanks!

Upvotes: 1

Views: 621

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187034

You are describing a "debounce" function. I would either use one of many libraries that offer this, or at least abstract your own implementation into a function that handles debouncing in a generic way.

The idea is that you call the debounce function everytime something changes, but it's implementation only runs after the function has not been called in some amount of time.

Then you could do something like:

const doSearch = useCallback(
  debounce(async (input: string) => {
    try {
      setLoading(true)
      const res = await axios.get<Searchresult[]>(`search/input=${input}`)

      setSearchresults(res)
    } catch {
      setSearchResults([])
    }
    setLoading(false)
  }, 500), // 500ms is the debounce threshold
  [],
)

React.useEffect(() => {
  if (input.length > 1) {
    doSearch()
  } else {
    setSearchResults([])
  }
}, [input, doSearch])

Upvotes: 3

Related Questions