1

Why my debounce functionality is not working in a React app with hooks?

My goal is to fire a fetch request to get data from an API after some delay. In my particular case, I have an input field where a user can input a post ID. I don't want fire a fetch request on each number entered in an input field. I want to fire a request only after a user stopped entering data for 1 second. Here is my implementation:

import { useCallback, useEffect, useState } from 'react'
import './App.css'

function debounce(fn, ms) {
  let timeoutId
  return function (...args) {
    if (timeoutId) clearTimeout(timeoutId)
    timeoutId = setTimeout(() => {
      fn(...args)
    }, ms)
  }
}

function App() {
  const [input, setInput] = useState('')

  const fetchData = async () => {
    if (input !== '') {
      let res = await fetch(`https://jsonplaceholder.typicode.com/posts/${input}`)
      let resData = await res.json()
      console.log(resData)
    }
  }

  const fireRequest = useCallback(debounce(fetchData, 1000), [])

  useEffect(() => {
    fireRequest()
  }, [input])

  return (
    <div className='App'>
      <input type='text' onChange={(e) => setInput(e.target.value)} value={input}></input>
    </div>
  )
}

export default App

For some reason, it's not working. There are no errors, and it looks like my data is not being fetched(nothing logs to the console). What am I doing wrong ? Thank you.

Submitted December 26th 2020 by Admin

Answers
0

Try this:

useEffect(() => { const apiCallTimeoutId = setTimeout(() => { fireRequest() }, 1000); return () => clearTimeout(apiCallTimeoutId); }, [input]);

1 sec after the user stops typing the request will be fired.

Admin | 9 months ago



Relevant Questions