Async race condition

Race conditions in async code are a classic AI-generated bug that is hard to spot.

reactuseEffectrace conditionasync
typescript
function SearchComponent() {
  const [query, setQuery] = React.useState('')
  const [results, setResults] = React.useState<string[]>([])

  React.useEffect(() => {
    if (!query) return

    async function search() {
      const data = await fetchResults(query)
      setResults(data)
    }

    search()
  }, [query])

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

Question

What is the race condition bug here, and how would you fix it?