---
name: use_debounced_search
kind: component
lang: ts
domain: core
version: "1.0.0"
purity: impure
signature: "useDebouncedSearch<T>(opts: UseDebouncedSearchOptions<T>): UseDebouncedSearchResult<T>"
description: "Hook que combina input con debounce y fetch automatico. Espera N ms de inactividad tras el ultimo cambio antes de fetchear. Expone query, set_query, results, loading, error y clear."
tags: [search, debounce, hook, input, fetch, autocomplete, core, component]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [react]
params:
  - name: fetch_fn
    desc: "Funcion que recibe la query string y retorna Promise<T> con los resultados"
  - name: delay
    desc: "Ms de inactividad antes de ejecutar el fetch (default 300)"
  - name: initial_query
    desc: "Query inicial (default string vacio)"
  - name: fetch_on_empty
    desc: "Si hace fetch cuando la query es string vacio (default true)"
output: "Objeto con query, set_query, results, loading, error y clear"
tested: false
tests: []
test_file_path: ""
file_path: "frontend/functions/core/use_debounced_search.tsx"
props:
  - name: fetch_fn
    type: "(query: string) => Promise<T>"
    required: true
    description: "Funcion de fetch que recibe la query"
  - name: delay
    type: "number"
    required: false
    description: "Ms de debounce (default 300)"
  - name: initial_query
    type: "string"
    required: false
    description: "Query inicial (default '')"
  - name: fetch_on_empty
    type: "boolean"
    required: false
    description: "Fetch cuando query es vacio (default true)"
emits: []
has_state: true
framework: react
variant: [default]
---

## Ejemplo

```tsx
import { useDebouncedSearch } from '@/functions/core/use_debounced_search'
import { apiClient } from '@/functions/core/api_client'

const api = apiClient({ base_url: 'http://localhost:8484/api' })

interface User { id: string; name: string; email: string }

function UserSearch() {
  const { query, set_query, results, loading } = useDebouncedSearch<User[]>({
    fetch_fn: (q) => api.get('/users/search', { q }),
    delay: 300,
    fetch_on_empty: false,  // No buscar cuando el input esta vacio
  })

  return (
    <div>
      <input
        value={query}
        onChange={(e) => set_query(e.currentTarget.value)}
        placeholder="Buscar usuarios..."
      />
      {loading && <span>Buscando...</span>}
      {results?.map((u) => <div key={u.id}>{u.name}</div>)}
    </div>
  )
}
```

## Notas

- Cancela el timer anterior en cada keystroke — solo ejecuta el fetch tras N ms de silencio
- `clear()` cancela el timer pendiente y limpia estado
- `fetch_on_empty: false` es util para autocomplete (no buscar con input vacio)
- `fetch_on_empty: true` (default) es util para filtros (mostrar todos sin query)
