Published
- 4 min read
Render Props: Una forma flexible de compartir código en React

¡Hola! Hoy vamos a hablar de una de las técnicas más interesantes en React: el patrón render props. Si alguna vez te has preguntado cómo compartir lógica entre componentes de forma elegante, este artículo es para ti.
¿Qué son las render props?
Imagina que tienes un componente que hace algo genial (como manejar un estado complejo o hacer una petición a una API) y quieres compartir esa funcionalidad con otros componentes. Las render props te permiten hacer exactamente eso, y de una manera muy flexible.
Las tres formas de pasar componentes como props
1. Como elemento (la forma más simple)
// La forma más directa
<MiComponente>
<OtroComponente />
</MiComponente>
Es como decir “hey, aquí tienes este componente, úsalo”. Simple y directo, pero no muy flexible.
2. Como función (la forma render props)
// La forma render props
<MiComponente>{(datos) => <OtroComponente datos={datos} />}</MiComponente>
Esta es la forma más poderosa. Es como decir “hey, aquí tienes estos datos, haz con ellos lo que quieras”. Te da total libertad para decidir cómo usar los datos.
3. Como componente (la forma más moderna)
// La forma componente
<MiComponente as={OtroComponente} />
Es como decir “hey, usa este componente como plantilla”. Es una forma más declarativa y limpia.
Ejemplo Práctico: Un Contador Reutilizable
Vamos a ver un ejemplo práctico de cómo podemos crear un contador reutilizable usando las tres formas:
// Nuestro componente base que maneja la lógica
const Contador = ({ children, as: Component }) => {
const [count, setCount] = useState(0);
// Si nos pasan un componente, lo usamos
if (Component) {
return <Component count={count} incrementar={() => setCount((c) => c + 1)} />;
}
// Si nos pasan una función, la ejecutamos
if (typeof children === 'function') {
return children({ count, incrementar: () => setCount((c) => c + 1) });
}
// Si nos pasan elementos, los renderizamos
return (
<div>
<p>Contador: {count}</p>
<button onClick={() => setCount((c) => c + 1)}>Incrementar</button>
{children}
</div>
);
};
Usando el contador de las tres formas:
// 1. Como elemento
<Contador>
<p>¡Este es un contador genial!</p>
</Contador>
// 2. Como función (render props)
<Contador>
{({ count, incrementar }) => (
<div>
<h2>Mi contador personalizado</h2>
<p>Valor: {count}</p>
<button onClick={incrementar}>
¡Haz clic aquí!
</button>
</div>
)}
</Contador>
// 3. Como componente
<Contador as={MiContadorPersonalizado} />
¿Cuándo usar cada forma?
Usa elementos cuando:
- Solo necesitas renderizar contenido estático
- No necesitas acceder a la lógica del componente padre
- Quieres una sintaxis simple y directa
Usa render props cuando:
- Necesitas acceso a la lógica del componente padre
- Quieres máxima flexibilidad en cómo renderizar el contenido
- Estás creando componentes reutilizables
Usa componentes cuando:
- Quieres una sintaxis más declarativa
- Tienes un componente específico que quieres usar como plantilla
- Prefieres un estilo más moderno y limpio
Un ejemplo más realista: Un componente de datos
const DatosUsuario = ({ children, as: Component }) => {
const [usuario, setUsuario] = useState(null);
const [cargando, setCargando] = useState(true);
useEffect(() => {
// Simulamos una petición a una API
fetchUsuario().then((data) => {
setUsuario(data);
setCargando(false);
});
}, []);
if (Component) {
return <Component usuario={usuario} cargando={cargando} />;
}
if (typeof children === 'function') {
return children({ usuario, cargando });
}
if (cargando) return <div>Cargando...</div>;
return (
<div>
<h2>Datos del usuario</h2>
{children}
</div>
);
};
Tips y trucos
-
Nombra tus props de forma descriptiva:
// Bien <Component render={({ data }) => <OtroComponente data={data} />} /> // Mejor <Component renderContent={({ userData }) => <Perfil data={userData} />} />
-
Usa TypeScript para mejor autocompletado:
interface RenderProps { data: UserData; loading: boolean; error?: Error; } <Component render={(props: RenderProps) => <OtroComponente {...props} />} />;
-
Combina patrones cuando tenga sentido:
<Contador> {({ count }) => ( <DatosUsuario> {({ usuario }) => ( <div> <h1>¡Hola {usuario.nombre}!</h1> <p>Has visitado {count} veces</p> </div> )} </DatosUsuario> )} </Contador>
Conclusión
Las render props son como tener un superpoder en React. Te permiten compartir lógica de forma flexible y reutilizable. La clave está en elegir la forma que mejor se adapte a tus necesidades:
- ¿Quieres simplicidad? Usa elementos
- ¿Quieres flexibilidad? Usa render props
- ¿Quieres claridad? Usa componentes
Recuerda: no hay una forma “correcta” de hacerlo, sino la forma que mejor se adapte a tu caso de uso.