DOM & Browsermedium

Build a debounced SearchInput component

Create a search field that calls `onSearch(term: string)` only after the user stops typing for `delayMs` (e.g. 300ms). Clear the timer on unmount and whenever the delay restarts. The input should remain responsive (updates every keystroke).

Asked at Amazon, Uber, Netflix

#react#debounce#useEffect#controlled input

Answer

function SearchInput({ onSearch, delayMs = 300, ...inputProps }) {
  const [value, setValue] = React.useState('')

  React.useEffect(() => {
    const id = window.setTimeout(() => {
      onSearch(value)
    }, delayMs)
    return () => window.clearTimeout(id)
  }, [value, delayMs, onSearch])

  return (
    <input
      {...inputProps}
      value={value}
      onChange={(e) => setValue(e.target.value)}
    />
  )
}

// Interview follow-ups:
// 1) If parent passes an unstable onSearch, the effect re-runs every render —
//    wrap parent callbacks in useCallback or debounce inside a ref-stable API.
// 2) For immediate first run on mount, either call onSearch('') once or skip
//    until value.length >= minChars — state that assumption.
// 3) AbortController pairs naturally with fetch inside the parent onSearch.

// Stable callback variant (parent should still memoize onSearch):
// const onSearchRef = React.useRef(onSearch)
// React.useEffect(() => { onSearchRef.current = onSearch })
// useEffect(() => { const t = setTimeout(() => onSearchRef.current(value), delayMs); ... }, [value, delayMs])

Source: common React screen interview

Practise more DOM & Browser questions →