Los Higher Order Components (HOC) en React son funciones que reciben un componente y devuelven otro componente, permitiendo reutilizar lógica como loaders, estilos o props compartidos. Aunque hoy los hooks han tomado protagonismo, entender este patrón te da bases sólidas para leer código legacy y diseñar abstracciones reutilizables en aplicaciones React con TypeScript.
Qué es un higher order component y para qué sirve
Un higher order component es simplemente una función que toma un componente como parámetro y retorna otro componente envolviéndolo con funcionalidad extra. La idea es no repetir lógica entre componentes que comparten comportamiento, por ejemplo, mostrar un loader mientras llega información desde una API.
¿Qué es un Higher Order Component en React? Es una función que recibe un componente y devuelve otro componente con lógica añadida, como autenticación, estilos o estados de carga, sin modificar el componente original.
En el ejercicio práctico se construye un HOC llamado withLoading que decide si renderizar un texto de loading o el componente real, dependiendo de un booleano que recibe por props [00:38].
Cómo se construye un HOC con TypeScript paso a paso
La estructura base parte de una función que recibe el componente y retorna otra función componente. Dentro se hace destructuring de las props para separar isLoading del resto y decidir qué renderizar [03:30].
Cómo tipar las props genéricas con TypeScript
Aquí entra el poder de TypeScript con generics. Se declara un tipo T que extiende de Object para representar las props desconocidas del componente envuelto, y se combina con isLoading como booleano fijo [05:20].
tsx
function withLoading<T extends Object>(Component: React.ComponentType<T>) {
return (props: T & { isLoading: boolean }) => {
const { isLoading, ...rest } = props;
return isLoading ? <p>loading...</p> : <Component {...(rest as T)} />;
};
}
El truco está en usar as T al pasar el resto de props, para que TypeScript no se queje de que isLoading no es asignable al componente original [06:10].
Cómo aplicar el HOC a un componente real
Se crea un UserComponent tipado con React.FunctionComponent<UserProps> que recibe un name de tipo string y renderiza un saludo. Luego se envuelve con la función withLoading para generar un nuevo componente llamado UserWithLoading [07:45].
tsx
interface UserProps {
name: string;
}
const UserComponent: React.FC<UserProps> = ({ name }) => (
<h1>Hello, {name}!</h1>
);
const UserWithLoading = withLoading(UserComponent);
Al renderizar <UserWithLoading isLoading={true} name="devcode" /> verás el texto loading, y al pasar isLoading={false} aparecerá el saludo completo [09:05].
Por qué los hooks desplazaron a los higher order components
Los higher order components siguen funcionando, pero los custom hooks ofrecen una forma más directa de compartir lógica sin envolver componentes ni lidiar con jerarquías profundas en el árbol de React. El patrón HOC añade capas de anidamiento que hacen el debugging más complejo, mientras que un hook se consume como una función dentro del propio componente.
¿Cuándo usar HOC en lugar de hooks? Úsalos cuando trabajes con código legacy, integraciones con librerías que aún los expongan (como connect de Redux clásico) o cuando necesites envolver el render completo de un componente.
Entre los conceptos clave que aparecen en la implementación están el destructuring de props con rest, los generics de TypeScript para tipar entradas desconocidas, el uso de React.ComponentType<T> para describir cualquier componente, y la sintaxis extends Object que restringe el genérico a objetos válidos [05:50].
¿Has implementado higher order components en alguna aplicación real? Cuéntame en los comentarios cómo quedó tu versión y qué casos de uso le encontraste antes de migrar a hooks.