SEPARAR contenedores (lógica de datos/negocio) de componentes presentacionales (solo UI). Prevenir componentes dios, perforación de props y bundles de cliente innecesarios. Hooks personalizados unen datos y UI. TanStack Query v5+ para toda obtención de datos del cliente. Server Components por defecto en Next.js. Activadores: "create (a|a) component", "build (the|a) UI", "refactor (the|the) frontend", archivo de componente excede 250 líneas.
Instrucciones de origen · Vista previa de solo lectura
name
Component Architecture
description
SEPARAR contenedores (lógica de datos/negocio) de componentes presentacionales (solo UI). Prevenir componentes dios, perforación de props y bundles de cliente innecesarios. Hooks personalizados unen datos y UI. TanStack Query v5+ para toda obtención de datos del cliente. Server Components por defecto en Next.js. Activadores: "create (a|a) component", "build (the|a) UI", "refactor (the|the) frontend", archivo de componente excede 250 líneas.
Se construye una nueva página o funcionalidad de UI compleja
Un archivo de componente excede 250 líneas
El usuario dice "refactor the frontend" o "split this component"
Se añade lógica de obtención de datos a un componente UI
PRINCIPIO FUNDAMENTAL
Cada componente es de uno de dos tipos:
Tipo
¿Estado de dominio?
¿Solo estado UI?
¿Efectos secundarios?
Ejemplo
Contenedor
Obtiene, gestiona o muta datos de dominio
Puede tener también estado UI
Sí
UserProfilePage, DashboardLayout
Presentacional
NUNCA toca datos de dominio
Puede tener estado UI local
No
Button, Card, Collapsible, Tabs
MATIZ CRÍTICO: El estado UI (isOpen, activeTab) está BIEN en componentes Presentacionales. Los datos de dominio (user, orders, projects) NO.
REGLA: Un componente Presentacional NUNCA DEBE importar funciones de obtención de datos, clientes API o consumidores de contexto de dominio. Los datos de dominio fluyen SOLO a través de props.
DECIDIR: Selección de Arquitectura
SI se construye desde cero →
EJECUTAR Pasos 1-5 en orden
SI el componente excede 250 líneas →
EJECUTAR Paso 6 (flujo de división)
SI el componente existente tiene 5+ props →
CONSIDERAR composición (react-composition/SKILL.md)
SI el componente es UI pura (Button, Card, Input) →
SALTAR al Paso 2 (crear solo Presentacional)
SI es full-stack (Next.js App Router) →
PREFERIR Server Components (Paso 5)
Solo usar 'use client' para hojas interactivas
EJECUTAR: Instrucciones
Paso 1: Definir Requisitos de Datos Primero
Antes de escribir cualquier JSX, listar qué datos necesita la funcionalidad:
Funcionalidad: [nombre]
Datos necesarios:
- [fuente de datos 1]
- [fuente de datos 2]
- [fuente de datos 3]
Fuentes:
- GET [endpoint 1]
- GET [endpoint 2]
Paso 2: Crear Componentes Presentacionales
Componentes UI puros que reciben datos a través de props:
Paso 5: Empujar 'use client' a las Hojas, Server Components por Defecto
// ❌ INCORRECTO: Toda la página es componente cliente'use client';
exportdefaultfunctionPage() { /* todo */ }
// ✅ CORRECTO: Solo la parte interactiva es componente clienteimport { InteractiveForm } from'./InteractiveForm'; // ESTE archivo tiene 'use client'exportdefaultfunctionPage() {
return (
<div><h1>Settings</h1> {/* Renderizado en servidor */}
<InteractiveForm /> {/* Hoja renderizada en cliente */}
</div>
);
}
Paso 6: Dividir un Componente de 250+ Líneas
Cuando el componente excede 250 líneas, seguir este flujo:
1. EXTRAER hooks personalizados PRIMERO
Mover TODA la lógica de estado + obtención de datos a un hook use[Funcionalidad]
→ A menudo reduce el componente 30-50%
2. EXTRAER subcomponentes presentacionales
Identificar regiones UI distintas (encabezado, barra lateral, lista, panel de detalle)
→ Extraer cada una en su propio componente Presentacional
3. EXTRAER funciones de utilidad
Cálculos puros, formateadores, validadores → utils/ o lib/
4. DIVIDIR por preocupación si aún es demasiado grande
UserProfile → UserProfileView + UserProfileEdit + UserProfileActivity
REGLAS MEDIBLES
Métrica
Límite
Acción
Líneas de archivo de componente
250
Dividir siguiendo Paso 6
Props personalizadas por componente
5
Usar composición o agrupar en objeto
Llamadas useState por componente
5
Extraer hook personalizado o usar useReducer
VALIDAR: Puertas de Calidad
Conteo de líneas: Ningún archivo de componente excede 250 líneas
Sin obtención en Presentacional: Buscar en components/ui/ por fetch(, useQuery, import.*api, CERO resultados
Sin fetch() crudo en hooks: Todos los hooks personalizados usan TanStack Query (useQuery/useMutation), sin fetch() crudo
'use client' en hojas: Directivas en componentes hoja, no en layouts de nivel página