Yeda AI Tips · #111

English

El estado del servidor va en una capa de caché, no en el estado global

¿Guardas datos del backend en el estado global? Eso es una fábrica de bugs. Cada lista que copias del servidor a un store es una segunda fuente de verdad que empieza a pudrirse en cuanto llega — y cada componente generado por IA que la lee hereda esa podredumbre.

El estado del servidor no es estado del cliente

El estado del cliente es data que tu app posee: la pestaña abierta, el borrador de un formulario, el modo oscuro. Solo cambia cuando tu código lo cambia, así que un store lo modela perfecto.

El estado del servidor es data prestada. Como dice Dominik Dorfmeister (mantenedor de TanStack Query): "tu app no la posee… Es el servidor quien es dueño de los datos." Vive en remoto, llega de forma asíncrona, otras personas pueden cambiarla sin que lo sepas, y puede quedar obsoleta en tu app en cualquier momento. La propia documentación de Redux traza la línea: "data fetching and caching" es un conjunto de problemas distinto de "state management".

Tratar ambos igual es el bug de raíz. Una copia de /api/todos en el store es correcta exactamente hasta que alguien más toca el backend.

Qué te da una capa de caché

Hacer fetch a mano hacia un store implica reimplementar, mal, todo lo que una capa de caché de datos — TanStack (React) Query, SWR, RTK Query, o equivalentes en otros ecosistemas — trae por defecto:

ProblemaStore hecho a manoCapa de caché
CachingCopia manual, sin expiraciónCaché por clave; entradas inactivas se recolectan (gcTime por defecto: 5 min en TanStack Query)
DeduplicaciónDos componentes = dos requestsMisma clave = un request, resultado compartido
Datos obsoletosDesconocido hasta el reporte de bugstaleTime marca fresh/stale; lo obsoleto se refresca en segundo plano
InvalidaciónBuscar cada reducer con una copiaUna llamada: invalidateQueries({ queryKey: ['todos'] })
Estados de carga/errorFlags repetidos por endpointDevueltos por query, automáticamente

Hasta el tutorial oficial de Redux admite el boilerplate: thunk asíncrono, request, flags de carga, handlers pending/fulfilled/rejected — por endpoint — y recomienda RTK Query "como el enfoque por defecto para data fetching en apps Redux".

El refactor en un snippet

// Before: server data smeared into a global store
useEffect(() => {
  fetch('/api/todos')
    .then(r => r.json())
    .then(data => dispatch(setTodos(data)));  // now stale forever
}, []);

// After: the cache layer owns it
const { data, isPending, error } = useQuery({
  queryKey: ['todos'],
  queryFn: () => fetch('/api/todos').then(r => r.json()),
});

// After any mutation, invalidate — every reader refetches:
queryClient.invalidateQueries({ queryKey: ['todos'] });

Diez componentes pueden llamar ese mismo useQuery y el request se deduplica a uno. Borra el slice, el thunk y los flags de carga.

Por qué importa más con código generado por IA

Los agentes de código imitan los patrones de tu codebase. Si la data del servidor vive en un store, cada componente generado inventa su propio baile de fetch-then-dispatch, cada uno con sus propios bugs de datos obsoletos — los componentes se desincronizan del backend y entre sí. Si la convención es "la data del servidor viene de la capa de caché, indexada por recurso", el código generado converge a un solo patrón correcto: entra una query key, sale data fresca. La arquitectura se vuelve el guardarraíl.

Trucos avanzados

Recursos

¿Viste el reel? Este artículo es la versión a fondo del tip #111 de Yeda AI Tips. Yeda AI diseña, audita y entrega flujos de ingeniería asistidos por IA en producción.

Habla con nosotros · Lee el blog · Read in English