4. Componentes en React
🧩 4.1 ¿Qué es un componente?
Section titled “🧩 4.1 ¿Qué es un componente?”Definición
Section titled “Definición”Un componente es una pieza de código reutilizable que representa una parte de la interfaz de usuario. Es como un bloque de construcción que puedes usar múltiples veces en tu aplicación.
| Característica | Descripción |
|---|---|
| Reutilizable | Se puede usar múltiples veces |
| Independiente | Tiene su propia lógica y UI |
| Composable | Se pueden combinar componentes |
| Encapsulado | Contiene su propio código |
Analogía visual
Section titled “Analogía visual”// Piensa en componentes como piezas de LEGO
// Una página web puede verse así:<App><Header /> // Componente de encabezado<Sidebar /> // Componente de barra lateral<MainContent> // Componente de contenido principal <ArticleCard /> // Componente de tarjeta <ArticleCard /> // Mismo componente, reutilizado <ArticleCard /> // Mismo componente, reutilizado</MainContent><Footer /> // Componente de pie de página</App>Ejemplo básico de componente
Section titled “Ejemplo básico de componente”// Un componente es una función que retorna JSXfunction Saludo() {return <h1>¡Hola, bienvenido!</h1>;}
// Usar el componentefunction App() {return ( <div> <Saludo /> <Saludo /> <Saludo /> </div>);}
// Resultado: Tres títulos "¡Hola, bienvenido!"🔧 4.2 Componentes funcionales
Section titled “🔧 4.2 Componentes funcionales”Sintaxis de componentes funcionales
Section titled “Sintaxis de componentes funcionales”En React moderno, los componentes son funciones de JavaScript que retornan JSX.
// Componente funcional básicofunction MiComponente() {return <div>Contenido del componente</div>;}
// Componente con arrow functionconst MiComponente = () => {return <div>Contenido del componente</div>;};
// Componente con return implícitoconst MiComponente = () => <div>Contenido del componente</div>;Reglas para nombrar componentes
Section titled “Reglas para nombrar componentes”| Regla | Ejemplo correcto | Ejemplo incorrecto |
|---|---|---|
| PascalCase | MiComponente | miComponente |
| Nombre descriptivo | BotonEnviar | Btn1 |
| Sustantivo | TarjetaUsuario | MostrarUsuario |
// ✅ BIEN - PascalCasefunction TarjetaProducto() {return <div>Producto</div>;}
// ❌ MAL - camelCase (React no lo reconoce como componente)function tarjetaProducto() {return <div>Producto</div>;}
// ✅ BIEN - Nombre descriptivofunction BotonAgregarCarrito() {return <button>Agregar al carrito</button>;}
// ❌ MAL - Nombre poco descriptivofunction Btn() {return <button>Agregar al carrito</button>;}📐 4.3 Estructura de un componente
Section titled “📐 4.3 Estructura de un componente”Anatomía de un componente
Section titled “Anatomía de un componente”// 1. Importacionesimport { useState } from 'react';import './MiComponente.css';
// 2. Definición del componentefunction MiComponente() {// 3. Lógica del componente (variables, funciones, hooks)const titulo = "Mi Título";const fecha = new Date().toLocaleDateString();
const handleClick = () => { console.log("Clic!");};
// 4. Return con JSXreturn ( <div className="mi-componente"> <h1>{titulo}</h1> <p>Fecha: {fecha}</p> <button onClick={handleClick}>Clic aquí</button> </div>);}
// 5. Exportaciónexport default MiComponente;Ejemplo práctico: Tarjeta de producto
Section titled “Ejemplo práctico: Tarjeta de producto”// components/ProductCard.jsximport './ProductCard.css';
function ProductCard() {const producto = { nombre: "Laptop Gaming", precio: 1299.99, imagen: "/laptop.jpg", disponible: true};
return ( <div className="product-card"> <img src={producto.imagen} alt={producto.nombre} /> <h3>{producto.nombre}</h3> <p className="precio">${producto.precio}</p> <span className={producto.disponible ? "disponible" : "agotado"}> {producto.disponible ? "Disponible" : "Agotado"} </span> <button>Agregar al carrito</button> </div>);}
export default ProductCard;📦 4.4 Props (envío de datos)
Section titled “📦 4.4 Props (envío de datos)”¿Qué son las Props?
Section titled “¿Qué son las Props?”Las props (propiedades) son la forma de pasar datos de un componente padre a un componente hijo. Son como los argumentos de una función.
// Componente que recibe propsfunction Saludo(props) {return <h1>Hola, {props.nombre}!</h1>;}
// Usar el componente pasando propsfunction App() {return ( <div> <Saludo nombre="Ana" /> <Saludo nombre="Carlos" /> <Saludo nombre="María" /> </div>);}
// Resultado:// Hola, Ana!// Hola, Carlos!// Hola, María!Desestructuración de props
Section titled “Desestructuración de props”// Sin desestructurarfunction Tarjeta(props) {return ( <div> <h2>{props.titulo}</h2> <p>{props.descripcion}</p> </div>);}
// Con desestructuración (más limpio)function Tarjeta({ titulo, descripcion }) {return ( <div> <h2>{titulo}</h2> <p>{descripcion}</p> </div>);}
// Uso<Tarjeta titulo="Mi título" descripcion="Mi descripción" />Props con valores por defecto
Section titled “Props con valores por defecto”// Valores por defecto en la desestructuraciónfunction Boton({ texto = "Enviar", color = "blue", size = "medium" }) {return ( <button className={size} style={{ backgroundColor: color }} > {texto} </button>);}
// Uso<Boton /> // Usa todos los valores por defecto<Boton texto="Guardar" /> // Solo cambia el texto<Boton texto="Cancelar" color="red" size="small" />Tipos de datos en props
Section titled “Tipos de datos en props”function Componente({// Stringnombre,// Númeroedad,// Booleanoactivo,// Arrayitems,// Objetousuario,// FunciónonClick}) {return <div>...</div>;}
// Pasar diferentes tipos de props<Componentenombre="Ana"edad={25}activo={true}items={["a", "b", "c"]}usuario={{ id: 1, nombre: "Ana" }}onClick={() => console.log("clic")}/>👶 4.5 Props children
Section titled “👶 4.5 Props children”¿Qué es children?
Section titled “¿Qué es children?”children es una prop especial que contiene todo lo que se coloca entre las etiquetas de apertura y cierre de un componente.
// Componente que usa childrenfunction Tarjeta({ children }) {return ( <div className="tarjeta"> {children} </div>);}
// Uso - todo lo de adentro es "children"<Tarjeta><h2>Título de la tarjeta</h2><p>Contenido de la tarjeta</p><button>Acción</button></Tarjeta>Ejemplo: Componente contenedor
Section titled “Ejemplo: Componente contenedor”// Componente Card reutilizablefunction Card({ children, titulo }) {return ( <div className="card"> <div className="card-header"> <h3>{titulo}</h3> </div> <div className="card-body"> {children} </div> </div>);}
// Uso con diferentes contenidos<Card titulo="Perfil de Usuario"><img src="avatar.jpg" alt="Avatar" /><p>Nombre: Ana García</p><p>Email: ana@email.com</p></Card>
<Card titulo="Estadísticas"><ul> <li>Ventas: 150</li> <li>Clientes: 45</li></ul></Card>Ejemplo: Layout con children
Section titled “Ejemplo: Layout con children”// Componente de Layoutfunction Layout({ children }) {return ( <div className="layout"> <header> <nav>Mi Sitio</nav> </header>
<main> {children} </main>
<footer> © 2024 Mi Sitio </footer> </div>);}
// Uso en diferentes páginasfunction PaginaInicio() {return ( <Layout> <h1>Bienvenido</h1> <p>Esta es la página de inicio</p> </Layout>);}
function PaginaContacto() {return ( <Layout> <h1>Contacto</h1> <form>...</form> </Layout>);}♻️ 4.6 Reutilización de componentes
Section titled “♻️ 4.6 Reutilización de componentes”Componente reutilizable
Section titled “Componente reutilizable”// Componente Button reutilizablefunction Button({children,variant = "primary",size = "medium",disabled = false,onClick}) {const className = `btn btn-${variant} btn-${size}`;
return ( <button className={className} disabled={disabled} onClick={onClick} > {children} </button>);}
// Múltiples usos del mismo componente<Button variant="primary" onClick={guardar}>Guardar</Button><Button variant="secondary" onClick={cancelar}>Cancelar</Button><Button variant="danger" size="small" onClick={eliminar}>Eliminar</Button><Button disabled>Procesando...</Button>Lista de tarjetas reutilizables
Section titled “Lista de tarjetas reutilizables”// Componente UserCardfunction UserCard({ nombre, email, avatar, rol }) {return ( <div className="user-card"> <img src={avatar} alt={nombre} /> <h3>{nombre}</h3> <p>{email}</p> <span className="rol">{rol}</span> </div>);}
// Reutilizar con diferentes datosfunction ListaUsuarios() {const usuarios = [ { id: 1, nombre: "Ana", email: "ana@mail.com", avatar: "/ana.jpg", rol: "Admin" }, { id: 2, nombre: "Carlos", email: "carlos@mail.com", avatar: "/carlos.jpg", rol: "Editor" }, { id: 3, nombre: "María", email: "maria@mail.com", avatar: "/maria.jpg", rol: "Usuario" }];
return ( <div className="lista-usuarios"> {usuarios.map(usuario => ( <UserCard key={usuario.id} nombre={usuario.nombre} email={usuario.email} avatar={usuario.avatar} rol={usuario.rol} /> ))} </div>);}📁 4.7 Organización de componentes
Section titled “📁 4.7 Organización de componentes”Estructura de carpetas recomendada
Section titled “Estructura de carpetas recomendada”src/├── components/│ ├── common/ # Componentes genéricos│ │ ├── Button/│ │ │ ├── Button.jsx│ │ │ └── Button.css│ │ ├── Card/│ │ │ ├── Card.jsx│ │ │ └── Card.css│ │ └── Input/│ │ ├── Input.jsx│ │ └── Input.css│ ├── layout/ # Componentes de estructura│ │ ├── Header.jsx│ │ ├── Footer.jsx│ │ └── Sidebar.jsx│ └── features/ # Componentes específicos│ ├── ProductCard.jsx│ └── UserProfile.jsx├── pages/│ ├── Home.jsx│ └── About.jsx└── App.jsxImportar y exportar componentes
Section titled “Importar y exportar componentes”// components/Button/Button.jsxfunction Button({ children, onClick }) {return <button onClick={onClick}>{children}</button>;}
export default Button;
// ----------------------------------------
// Importar en otro archivoimport Button from './components/Button/Button';
function App() {return <Button onClick={() => alert("Hola")}>Clic</Button>;}📝 Resumen
Section titled “📝 Resumen”
🐝