Fundamentos de React: componentes y props
Al finalizar este tema
Podrás crear componentes en React, pasar datos mediante props y componer la interfaz combinando múltiples componentes.
¿Por qué React?
Es posible crear páginas web con HTML y JavaScript puros. Sin embargo, a medida que la página se vuelve más compleja, surgen problemas:
<!-- Si tuvieras que repetir la misma estructura de tarjeta 10 veces? -->
<div class="card">
<h3>Primer elemento</h3>
<p>Descripción...</p>
</div>
<div class="card">
<h3>Segundo elemento</h3>
<p>Descripción...</p>
</div>
<!-- ... 8 veces más -->Al copiar y pegar HTML, es necesario modificar las 10 partes cada vez que se cambia el diseño. React resuelve este problema mediante los componentes, que permiten crear fragmentos de interfaz de usuario reutilizables a partir de una única unidad.
¿Qué es un componente?
Un componente es una función que genera la interfaz de usuario.
function Card() {
return (
<div className="card">
<h3>Título</h3>
<p>Descripción</p>
</div>
);
}Este es un componente. Esta sintaxis, similar a HTML, se conoce como JSX. Es una sintaxis que permite incluir marcado dentro de JavaScript. Dado que el navegador no puede interpretar JSX directamente, se transforma en JavaScript estándar durante el proceso de compilación.
El nombre del componente siempre debe comenzar con una mayúscula. Si comienza con una minúscula, React lo interpretará como una etiqueta HTML.
Uso de componentes
Se utiliza un componente creado dentro de otro componente como si fuera una etiqueta:
function App() {
return (
<div>
<Card />
<Card />
<Card />
</div>
);
}Escribir <Card /> tres veces renderiza la misma interfaz de usuario tres veces. Si quieres cambiar el diseño, solo necesitas modificar la función Card.
Props: pasar datos a los componentes
Hasta ahora, los Card siempre han mostrado el mismo contenido. Si quieres que cada tarjeta muestre datos diferentes, utiliza Props (abreviatura de Properties).
function Card(props) {
return (
<div className="card">
<h3>{props.title}</h3>
<p>{props.description}</p>
</div>
);
}
function App() {
return (
<div>
<Card title="HTML" description="El esqueleto de la web" />
<Card title="CSS" description="La ropa de la web" />
<Card title="JS" description="El cerebro de la web" />
</div>
);
}{props.title} — En JSX, las llaves {} indican que se insertará un valor de JavaScript. Las props son datos que se transmiten desde el componente padre al componente hijo en una dirección unidireccional.
Recepción de props mediante la desestructuración
Usar props.title y props.description repetidamente puede ser tedioso. En la práctica, se utiliza la desestructuración:
function Card({ title, description }) {
return (
<div className="card">
<h3>{title}</h3>
<p>{description}</p>
</div>
);
}Extrae directamente de los parámetros de la función como { title, description }. El significado es el mismo, pero el código es más legible.
Diversos tipos de props
Se pueden pasar a las props no solo cadenas, sino también números, arreglos, objetos y funciones:
function UserProfile({ name, age, hobbies, onFollow }) {
return (
<div>
<h2>{name} ({age} años)</h2>
<ul>
{hobbies.map((hobby, i) => (
<li key={i}>{hobby}</li>
))}
</ul>
<button onClick={onFollow}>Seguir</button>
</div>
);
}
// Uso
<UserProfile
name="Chulsoo"
age={25}
hobbies={["Programación", "Juegos", "Lectura"]}
onFollow={() => alert("¡Seguido!")}
/>Las cadenas se envían entre comillas, y los demás valores se envían entre llaves {}. El patrón de iterar sobre una matriz con map() para renderizar una lista es muy común en React.
children: una prop especial
El contenido que se coloca entre las etiquetas de un componente se pasa como una prop especial llamada children:
function Container({ children }) {
return (
<div className="container">
{children}
</div>
);
}
// Uso
<Container>
<h1>Título</h1>
<p>Todo lo que se coloca aquí son children</p>
</Container>Al utilizar children, se pueden crear componentes de diseño: un patrón en el que el marco exterior permanece fijo y solo cambia el contenido interior.
Criterios para la separación de componentes
¿Cuándo se deben separar los componentes?
- Fragmentos de la interfaz de usuario que se repiten → extraerlos como componentes.
- Unidades de funcionalidad independientes → separarlas como componentes.
- Cuando la pantalla se vuelve demasiado larga → separarla en secciones.
App
├── Header
├── Main
│ ├── SearchBar
│ └── CardList
│ ├── Card
│ ├── Card
│ └── Card
└── FooterEsta es la idea central de React: combinar elementos en una estructura de árbol.
Establecer valores predeterminados para las propiedades
Se pueden establecer valores predeterminados en caso de que no se pasen las propiedades:
function Badge({ label = "NEW", color = "#3498db" }) {
return (
<span style={{
backgroundColor: color,
color: "white",
padding: "4px 8px",
borderRadius: "4px",
fontSize: "12px"
}}>
{label}
</span>
);
}
// Usar valores predeterminados
<Badge /> // "NEW" + azul
<Badge label="HOT" /> // "HOT" + azul
<Badge label="SALE" color="red" /> // "SALE" + rojoSi se definen valores predeterminados, quienes utilicen el componente no tendrán que pasar todas las propiedades una por una. Solo deberán especificar las propiedades que necesiten, de forma opcional.
Aspectos importantes a tener en cuenta en JSX
JSX es similar a HTML, pero presenta algunas diferencias importantes:
// 1. className en lugar de class
<div className="container"> // ✅
<div class="container"> // ❌ class es una palabra reservada de JavaScript
// 2. htmlFor en lugar de for
<label htmlFor="email">Correo electrónico</label> // ✅
// 3. Debe estar envuelto en un único elemento raíz
function Wrong() {
return (
<h1>Título</h1> // ❌ Dos elementos raíz
<p>Contenido</p>
);
}
function Right() {
return (
<> // ✅ Envolver con Fragment
<h1>Título</h1>
<p>Contenido</p>
</>
);
}
// 4. El estilo es un objeto
<div style={{ backgroundColor: "red", fontSize: "16px" }}>
// camelCase + valor de cadena
</div><> y </> se denominan Fragment. Permiten agrupar varios elementos sin necesidad de un contenedor <div> adicional.
Renderizado condicional
Se puede mostrar una interfaz de usuario diferente según el valor de las propiedades:
function StatusBadge({ isOnline }) {
return (
<span>
{isOnline ? "🟢 en línea" : "⚪ fuera de línea"}
</span>
);
}
function Notification({ count }) {
return (
<div>
notificaciones
{count > 0 && <span className="badge">{count}</span>}
</div>
);
}&& El operador renderiza el lado derecho solo si el lado izquierdo es verdadero. El operador ternario se utiliza cuando se deben mostrar tanto el valor verdadero como el falso. Estos dos patrones cubren la mayor parte del renderizado condicional en React.
Resumen clave
| Concepto | Descripción |
|---|---|
| Componente | Función que devuelve una interfaz de usuario (comienza con mayúscula) |
| JSX | Sintaxis para escribir marcado dentro de JavaScript |
| Props | Transmisión unidireccional de datos de padre a hijo |
| children | Propiedad especial que transmite el contenido entre etiquetas |
| Desestructuración | Recibir propiedades de forma limpia mediante la sintaxis ({ title }) |
| Valores predeterminados | Prepararse para valores no transmitidos mediante la sintaxis ({ label = "NEW" }) |
| Fragment | Eliminar divs contenedores innecesarios con <>...</> |
Al aprender React por primera vez, lo más importante es comprender "qué datos fluyen de dónde a dónde". Las propiedades siempre fluyen de arriba hacia abajo. Si un componente hijo desea modificar los datos del componente padre, el componente padre le pasa una función como propiedad, indicando "si llamas a esto, cambiaré mi estado"; esto se relaciona con el Estado (State), que aprenderás a continuación.
→ Aplicación biológica: DevBench — React Intro