Lección 4 de 12 · Lectura y práctica
High Order Components: Envolviendo Funcionalidad
CONCEPTO CLAVE: Un High Order Component (HOC) es una función que recibe un componente y devuelve un nuevo componente con funcionalidad adicional. No es un componente en sí mismo, sino un patrón que envuelve otros componentes para.
Del concepto a la práctica
Taller de esta lección
Un HOC añade una capacidad transversal sin modificar el componente recibido. Para que sea seguro, debe reenviar props, conservar una identidad descriptiva y documentar cuáles props controla y cuáles reenvía. En código nuevo conviene comparar esta complejidad con un hook o un Provider antes de adoptarlo.
Ejemplo resuelto
function withReadOnly(Wrapped) {
function ReadOnly(props) {
return <Wrapped {...props} canEdit={false} />;
}
ReadOnly.displayName = `withReadOnly(${Wrapped.displayName || Wrapped.name})`;
return ReadOnly;
}Si el componente recibe title:"Informe", conserva el título y obtiene canEdit=false.
Pruébalo
Crea un componente que muestre
titleycanEdit.Envuélvelo con
withReadOnly.Comprueba que el componente original no cambia y que la versión envuelta bloquea edición.
Comprueba tu resultado
Error frecuente: mutar Wrapped y añadirle propiedades directamente. Corrígelo devolviendo otro componente.
Ejercicio: pasa una prop role:"viewer" y verifica que aparece junto al título; el resultado esperado es una instancia nueva, con el original conservando su conducta inicial cuando recibe explícitamente canEdit=true.
withReadOnly impone canEdit=false en la presentación. La API debe volver a comprobar permisos antes de aceptar una escritura: un cliente puede llamar al endpoint sin pasar por el botón. Declara el HOC resultante fuera del cuerpo de render; cambiar su identidad en cada render puede remontar la vista y perder estado.
Este contrato sí sobrescribe intencionalmente canEdit con false al poner esa prop después de la propagación: una prop canEdit=true del consumidor no puede activar edición en la versión envuelta.

Mapa de prácticaEl control de acceso, las actualizaciones y las copias de seguridad cubren riesgos distintos. Una alerta necesita un procedimiento de respuesta para contener y recuperar el servicio. Varias capas reducen la exposición, pero ninguna garantiza seguridad absoluta.
Ver la infografía en tamaño completo ↗¿Qué problema resuelven los HOC?
Imaginemos que tenemos tres componentes que necesitan datos de autenticación. Sin HOC, repetiríamos la lógica de autenticación en cada componente. Con un HOC, envolvemos cada componente y automáticamente obtienen acceso a la información de usuario.
Sintaxis básica de un HOC
La estructura fundamental de un HOC sigue este patrón:
const withHOC = (WrappedComponent) => {
return function(props) {
// Lógica adicional aquí
const nuevaProp = 'dato inyectado';
return ;
}
};
// Uso
const ComponenteMejorado = withHOC(ComponenteOriginal);
with. Así withAuth, withTheme, withData comunican inmediatamente su propósito.HOC con Estado y Efectos
El verdadero poder de los HOC aparece cuando necesitamos compartir estado o lifecycle methods entre múltiples componentes:
import { useState, useEffect } from 'react';
const withMouseTracker = (WrappedComponent) => {
return function ConMouseTracker(props) {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (e) => {
setPosition({ x: e.clientX, y: e.clientY });
};
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return (
);
};
};
// Componente que usa el HOC
const PanelEstadistico = ({ mousePosition, titulo }) => (
{titulo}
Posición del mouse: X={mousePosition.x}, Y={mousePosition.y}
);
const PanelMejorado = withMouseTracker(PanelEstadistico);
Pasos para crear un HOC robusto
- Identifica la lógica repetida: Busca código que copies entre componentes similares.
- Crea la función HOC: Debe recibir el componente y retornar uno nuevo con las props adicionales.
- Pasa las props correctamente: Usa el spread operator para mantener las props originales.
- Considera las props omitidas: Si el HOC consume props internas,Documenta esas props en el nombre o propTypes.
- Agrega displayName: Facilita el debugging en React DevTools.
HOC con Múltiples Parámetros
Los HOC pueden recibir parámetros adicionales para configurarlos dinámicamente:
const withAuth = (WrappedComponent, opciones = {}) => {
const { requiereAdmin = false } = opciones;
return function ConAuth(props) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
verificarAuth().then((userData) => {
setUser(userData);
setLoading(false);
});
}, []);
if (loading) return Cargando...;
if (requiereAdmin && !user?.esAdmin) {
return Acceso denegado;
}
return ;
};
};
// Uso con configuración
const DashboardAdmin = withAuth(Dashboard, { requiereAdmin: true })(Dashboard);
Display Name para Debugging
En React DevTools, los componentes HOC pueden aparecer sin nombre. Corrige esto:
const withData = (WrappedComponent) => {
function ConData(props) {
// lógica...
return ;
}
ConData.displayName = `withData(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
return ConData;
};
HOC vs Render Props vs Hooks
| Criterio | HOC | Render Props | Hooks |
|---|---|---|---|
| Reutilización | Excelente | Buena | Excelente |
| Complejidad | Media | Baja | Baja |
| Props naming | Puede entrar en conflicto | Control total | Control total |
| Estilo dominante | Clásico | Legacy | Moderno |
HOC Real: withLoading
Un HOC práctico que muestra estados de carga:
const withLoading = (WrappedComponent) => {
return function ConLoading({ isLoading, error, ...props }) {
if (error) {
return (
Error al cargar
{error.message}
);
}
if (isLoading) {
return (
Cargando...
);
}
return ;
};
};
// Componente limpio
const ListaUsuarios = ({ usuarios }) => (
{usuarios.map(u => - {u.nombre}
)}
);
// Envuelto con loading
const ListaUsuariosConLoading = withLoading(ListaUsuarios);
// Uso: automáticamente maneja loading y error
<ListaUsuariosConLoading
isLoading={cargando}
error={error}
usuarios={usuarios}
/>
Los HOC son como trajes a la medida: envuelven tu componente existente con nuevas capacidades sin alterar el traje original.
Composición de HOC
Puedes encadenar múltiples HOC para combinar funcionalidades:
const App = withAuth(
withTheme(
withLoading(
Dashboard
)
)
);
// O con composición:
const compose = (...hocs) => (Component) =>
hocs.reduce((acc, hoc) => hoc(acc), Component);
const App = compose(
withAuth,
withTheme,
withLoading
)(Dashboard);
compose viene de librerías como Redux (connect) y Lodash (flow). Hace el código más legible cuando tienes muchos HOC.Cosas a Evitar
Ver más
- No modifiques el componente original: No uses
React.cloneElementparamutarlo. - No uses refs en props: Las refs no se pasan como props normales. Usa
forwardRefsi necesitas refs. - No copies props estáticas: Si el componente original tiene métodos estáticos, debes copiarlos manualmente.
// ❌ Incorrecto
const withEjemplo = (WrappedComponent) => {
return class extends React.Component {
render() {
const { exclude, ...props } = this.props;
return ;
}
};
};
// ✅ Correcto con forwardRef
const withEjemplo = (WrappedComponent) => {
function ConEjemplo(props, ref) {
return ;
}
return React.forwardRef(ConEjemplo);
};
Resumen Práctico
Los High Order Components siguen el principio de composición sobre herencia. Son ideales para:
- Compartir lógica de acceso a datos
- Inyectar props transversales (tema, auth, locale)
- Wrapper visuales (loading, error, wrapper de portal)
- Componentes con características comunes reutilizables
¿Cuál es la principal ventaja de usar HOC sobre copiar y pegar código en múltiples componentes?
- A) Los HOC hacen que el código sea más rápido
- B) Los HOC permiten compartir lógica sin modificar los componentes originales
- C) Los HOC eliminan la necesidad de props
- D) Los HOC son más fáciles de escribir que hooks
En la próxima lección exploraremos cómo los HOC se comparan con los Render Props y cuándo elegir cada patrón según el contexto de tu aplicación.
Sigue con React Intermedio: Patrones y Optimización
Esta lección forma parte de un curso de Cursalo. Revisa su programa y elige entre la compra individual o el acceso a toda la escuela.
Si ya tenías acceso a este curso, entra con tu cuenta: tus derechos y tu progreso se conservan. No necesitas comprarlo de nuevo.