Skip to content

Reglas de Estructura de Módulos React

Documento complementario: Estructura de Módulos React

Tabla de Decisiones Rápidas

¿Cuándo usar estructura por recurso vs plana?

Si tu módulo tiene...Usar
1-2 recursos, < 15 componentesEstructura plana
3+ recursos, 15+ componentesEstructura por recurso
Crecimiento previstoEstructura por recurso

¿Cuándo crear subcarpeta vs archivo plano?

EscenarioSoluciónEjemplo
Componente con 1 archivoArchivo planoDisciplinaForm.tsx
Componente con 2-3 archivos relacionadosSubcarpeta + index.tsxMiembroForm/index.tsx
Grupo de 3+ modales relacionadosSubcarpeta temáticaDisciplinaModals/AddModal.tsx
Componente complejo (4+ archivos)Subcarpeta organizadaMiembroForm/ con utils, types

¿Cuándo usar index.tsx vs nombre explícito?

ContextoUsarImport resultante
Componente principal de carpetaindex.tsximport Form from './MiembroForm'
Sub-componente en carpetaNombre explícitoimport { DatosBasicos } from './MiembroForm'
Componente standaloneNombre explícitoimport Form from './DisciplinaForm'
Múltiples componentes en carpetaindex.tsx + exportsimport { A, B } from './Modals'

Convenciones de Nomenclatura

En Subcarpetas de Componentes

Regla: Eliminar prefijos redundantes cuando el contexto lo da la carpeta.

Ubicación❌ Nombre Antiguo✅ Nombre NuevoRazón
MiembroForm/MiembroFormDatosBasicos.tsxDatosBasicos.tsxCarpeta ya dice "MiembroForm"
DisciplinaModals/AddMiembroDisciplinaModal.tsxAddModal.tsxCarpeta da contexto
ProductoModals/ConfirmDeleteMiembroProductoModal.tsxDeleteConfirmModal.tsxMás conciso

Excepción: Mantener prefijo si hay ambigüedad o si el componente se exporta fuera de su carpeta.

En Hooks

Tipo de HookUbicaciónNombre
Query/Mutation principal{Recurso}/hooks/use{Recurso}.ts
Lógica de negocio{Recurso}/hooks/use{Recurso}{Feature}.ts
Orquestación (modales){Recurso}/hooks/use{Recurso}{Feature}.ts
Sub-recurso relacionado{Recurso}/hooks/use{SubRecurso}.ts

Ejemplo:

Miembro/hooks/
├── useMiembro.ts              # useMiembroList, useCreateMiembro, etc.
├── useMiembroFormLogic.ts     # Lógica específica del formulario
├── useMiembroFormModals.ts    # Orquestación de modales
├── useMiembroDisciplina.ts    # Sub-recurso disciplinas
└── useMiembroProducto.ts      # Sub-recurso productos

En Services/Schemas/Types

Regla: Mirror Pattern - Reflejar la estructura de componentes.

Miembro/
├── components/
│   ├── MiembroForm/
│   └── DisciplinaModals/

├── services/
│   ├── miembro.service.ts       # ← Para MiembroForm
│   └── miembroDisciplina.service.ts  # ← Para DisciplinaModals

├── schemas/
│   ├── miembro.schema.ts
│   └── miembroDisciplina.schema.ts

└── types/
    ├── miembro.types.ts
    └── miembroDisciplina.types.ts

Patrones de Import

Imports dentro del mismo recurso

typescript
// Miembro/components/MiembroForm/index.tsx
import { DatosBasicos } from './DatosBasicos.js';  // Mismo directorio
import { useMiembroFormLogic } from '../../hooks/useMiembroFormLogic.js'; // 2 niveles arriba
import { miembroCreateSchema } from '../../schemas/miembro.schema.js';
import type { Miembro } from '../../types/miembro.types.js';

Imports entre recursos

typescript
// Categoria/components/AssignCategoriaModal.tsx
import { useMiembroList } from '../../Miembro/hooks/useMiembro.js';
import type { Miembro } from '../../Miembro/types/miembro.types.js';

Imports desde shared

typescript
// Miembro/components/MiembroForm/DatosBasicos.tsx
import { SelectionModeToggle } from '../../../shared/components/SelectionModeToggle.js';
import type { SelectionMode } from '../../../shared/types/selectionMode.types.js';

Imports desde core

typescript
// Miembro/components/MiembroForm/index.tsx
import { FormActions } from '../../../core/components/form/layout/FormActions.js';
import { useConfig } from '../../../core/context/ConfigContext.js';

Carpeta shared/

¿Qué va en shared/?

✅ Incluir:

  • Componentes usados por 2+ recursos diferentes
  • Types compartidos entre recursos (ej: SelectionMode)
  • Utilidades usadas por múltiples recursos

❌ No incluir:

  • Código usado solo por un recurso (mantenerlo en el recurso)
  • Código global del sistema (va en core/)

Estructura de shared/

shared/
├── components/           # Componentes compartidos del módulo
│   ├── SelectionModeToggle.tsx
│   └── BulkActionsBar.tsx

├── types/               # Types compartidos
│   ├── selectionMode.types.ts
│   └── bulkAssignment.types.ts

├── schemas/             # Validaciones compartidas
│   └── selectionMode.schema.ts

└── utils/              # Utilidades compartidas
    └── arrayHelpers.ts

Checklist de Calidad

Al crear un nuevo recurso:

  • [ ] Carpeta raíz con nombre PascalCase: {Recurso}/
  • [ ] Subcarpetas: components/, hooks/, services/, schemas/, types/, views/
  • [ ] Al menos un componente principal con index.tsx
  • [ ] Al menos un hook use{Recurso}.ts
  • [ ] Al menos un service {recurso}.service.ts
  • [ ] Al menos un schema {recurso}.schema.ts
  • [ ] Al menos un type {recurso}.types.ts
  • [ ] View principal en views/{Recurso}View.tsx

Al crear un componente complejo:

  • [ ] Crear subcarpeta si tiene 3+ archivos relacionados
  • [ ] Usar index.tsx para el componente principal
  • [ ] Eliminar prefijos redundantes en sub-componentes
  • [ ] Crear utils.ts si hay helpers específicos
  • [ ] Crear types.ts local si hay types solo de ese componente

Al organizar modales:

  • [ ] Si son 3+ modales del mismo tipo, crear carpeta {Tipo}Modals/
  • [ ] Usar nombres cortos: AddModal.tsx, EditModal.tsx, DeleteConfirmModal.tsx
  • [ ] Si es 1-2 modales, dejar en components/ directo

Ejemplos Reales

Recurso Simple (TipoRelacion)

TipoRelacion/
├── components/
│   └── TipoRelacionForm/
│       └── index.tsx
├── hooks/
│   ├── useTipoRelacion.ts
│   └── useTipoRelacionCrud.ts
├── services/
│   └── tipoRelacion.service.ts
├── schemas/
│   └── tipoRelacion.schema.ts
├── types/
│   └── tipoRelacion.types.ts
└── views/
    └── TipoRelacionView.tsx

Recurso Complejo (Miembro)

Miembro/
├── components/
│   ├── MiembroForm/
│   │   ├── index.tsx
│   │   ├── DatosBasicos.tsx
│   │   ├── DatosComerciales.tsx
│   │   ├── DatosMembresia.tsx
│   │   ├── AccionesAdicionales.tsx
│   │   └── utils.ts
│   ├── MiembroTable/
│   │   └── index.tsx
│   ├── AltaBajaModals/
│   │   ├── AltaMiembroModal.tsx
│   │   └── BajaMiembroModal.tsx
│   ├── DisciplinaModals/
│   │   ├── AddModal.tsx
│   │   ├── EditModal.tsx
│   │   ├── DeleteConfirmModal.tsx
│   │   └── ListModal.tsx
│   └── ProductoModals/
│       ├── AddModal.tsx
│       ├── EditModal.tsx
│       ├── DeleteConfirmModal.tsx
│       └── ListModal.tsx
├── hooks/
│   ├── useMiembro.ts
│   ├── useMiembroTableSSR.ts
│   ├── useMiembroFormLogic.ts
│   ├── useMiembroFormModals.ts
│   ├── useMiembroDisciplina.ts
│   └── useMiembroProducto.ts
├── services/
│   ├── miembro.service.ts
│   ├── miembroDisciplina.service.ts
│   └── miembroProducto.service.ts
├── schemas/
│   ├── miembro.schema.ts
│   ├── miembroDisciplina.schema.ts
│   └── miembroProducto.schema.ts
├── types/
│   ├── miembro.types.ts
│   ├── miembroDisciplina.types.ts
│   └── miembroProducto.types.ts
├── mappers/
│   └── miembro.mapper.ts
└── views/
    ├── MiembroView.tsx
    └── MiembroFormView.tsx

Anti-Patrones a Evitar

❌ Prefijos redundantes

typescript
// ❌ MAL
MiembroForm/
├── MiembroFormDatosBasicos.tsx
├── MiembroFormDatosComerciales.tsx
└── MiembroFormDatosMembresia.tsx

// ✅ BIEN
MiembroForm/
├── DatosBasicos.tsx
├── DatosComerciales.tsx
└── DatosMembresia.tsx

❌ Carpetas innecesarias

typescript
// ❌ MAL (componente simple con 1 archivo)
DisciplinaForm/
└── index.tsx

// ✅ BIEN
DisciplinaForm.tsx

❌ Mezclar concerns

typescript
// ❌ MAL
Miembro/
├── MiembroForm.tsx        # Componente
├── useMiembro.ts          # Hook
├── miembro.service.ts     # Service
└── DisciplinaModal.tsx    # ← De otro recurso!

// ✅ BIEN
Miembro/
├── components/
│   └── MiembroForm/
├── hooks/
│   └── useMiembro.ts
└── services/
    └── miembro.service.ts

Disciplina/
├── components/
│   └── DisciplinaModal.tsx

❌ shared/ como cajón de sastre

typescript
// ❌ MAL
shared/
├── MiembroHelpers.ts      # ← Específico de Miembro, no compartido
├── SelectionMode.tsx      # ✅ OK (usado por varios recursos)
└── CategoriaUtils.ts      # ← Específico de Categoria

// ✅ BIEN
Miembro/
└── utils/
    └── helpers.ts

shared/
└── components/
    └── SelectionMode.tsx

Categoria/
└── utils/
    └── utils.ts

Última actualización: 2026-01-29 Relacionado con: Estructura de Módulos React