---
name: use_fetch
kind: component
lang: ts
domain: core
version: "1.0.0"
purity: impure
signature: "useFetch<T>(opts: UseFetchOptions<T>): FetchState<T>"
description: "Hook GET con cache in-memory stale-while-revalidate. Muestra datos cacheados inmediatamente y refetchea en background. Soporta refetch_interval, refetch_on_focus, stale_time y retry."
tags: [fetch, hook, cache, swr, get, http, core, component, pendiente-usar]
uses_functions: [http_cache_ts_core]
uses_types: [FetchState_ts_core]
returns: []
returns_optional: false
error_type: "error_go_core"
imports: [react]
params:
  - name: url
    desc: "URL a fetchear (string). Actua como cache key."
  - name: fetch_fn
    desc: "Funcion de fetch alternativa que recibe la URL (ej: api.get de api_client). Si se omite usa fetch nativo."
  - name: enabled
    desc: "Si false no hace fetch automatico al montar (default true)"
  - name: stale_time
    desc: "Tiempo en ms antes de considerar datos stale y refetchear (default 30000)"
  - name: refetch_interval
    desc: "Intervalo en ms para refetch automatico. 0 desactiva (default 0)"
  - name: refetch_on_focus
    desc: "Si refetchea al recuperar foco de la ventana (default true)"
  - name: retry
    desc: "Numero de reintentos ante error (default 0)"
  - name: retry_delay
    desc: "Delay en ms entre reintentos (default 1000)"
output: "FetchState<T> con data, error, loading, is_stale y refetch"
tested: false
tests: []
test_file_path: ""
file_path: "frontend/functions/core/use_fetch.tsx"
props:
  - name: url
    type: "string"
    required: false
    description: "URL a fetchear"
  - name: fetch_fn
    type: "(url: string) => Promise<T>"
    required: false
    description: "Funcion de fetch alternativa (ej: api.get)"
  - name: enabled
    type: "boolean"
    required: false
    description: "Habilitar fetch automatico (default true)"
  - name: stale_time
    type: "number"
    required: false
    description: "Ms antes de considerar datos stale (default 30000)"
  - name: refetch_interval
    type: "number"
    required: false
    description: "Ms entre refetches automaticos (0 = off)"
  - name: refetch_on_focus
    type: "boolean"
    required: false
    description: "Refetch al recuperar foco (default true)"
  - name: retry
    type: "number"
    required: false
    description: "Reintentos ante error (default 0)"
  - name: retry_delay
    type: "number"
    required: false
    description: "Ms entre reintentos (default 1000)"
emits: []
has_state: true
framework: react
variant: [default]
---

## Ejemplo

```tsx
import { useFetch } from '@/functions/core/use_fetch'
import { apiClient } from '@/functions/core/api_client'

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

function UsersList() {
  const { data: users, loading, error, is_stale, refetch } = useFetch<User[]>({
    url: '/users',
    fetch_fn: api.get,
    stale_time: 10_000,
    refetch_on_focus: true,
  })

  if (loading && !users) return <div>Cargando...</div>
  if (error) return <div>Error: {error.message}</div>

  return (
    <div>
      {is_stale && <span>Actualizando...</span>}
      {users?.map((u) => <div key={u.id}>{u.name}</div>)}
      <button onClick={refetch}>Refrescar</button>
    </div>
  )
}
```

## Notas

- La URL actua como cache key — misma URL = mismos datos cacheados
- Stale-while-revalidate: si hay datos en cache y son stale, los muestra (`is_stale: true`) y refetchea en background
- Si no se pasa `fetch_fn`, usa `fetch` nativo con `Accept: application/json`
- Usar `enabled: false` para fetch condicional (ej: cuando falta un parametro)
