Aprende a crear componentes reutilizables y a estructurar tu aplicación React de forma profesional
midudev
Más clases y directos en YouTube
Creando el Componente JobCard
En esta clase vamos a continuar componetizando nuestra aplicación DevJobs. Ya tenemos separados el Header y el Footer. Ahora es el turno de la parte más importante: los JobCard (tarjetas de trabajo).
Creando la estructura de datos
Antes de crear los componentes, necesitamos tener datos de ejemplo. Vamos a definir un array con algunos trabajos en nuestro App.jsx:
function App() { const jobs = [ { id: 1, title: 'Frontend Developer', company: 'TechCorp', location: 'Madrid, España', salary: '€45,000 - €60,000', description: 'Estamos buscando un desarrollador frontend con experiencia en React.', tags: ['React', 'TypeScript', 'CSS'], }, { id: 2, title: 'Backend Developer', company: 'DataStack', location: 'Barcelona, España', salary: '€50,000 - €70,000', description: 'Desarrollador backend para trabajar con Node.js y bases de datos.', tags: ['Node.js', 'PostgreSQL', 'API'], }, { id: 3, title: 'Full Stack Developer', company: 'StartupX', location: 'Valencia, España', salary: '€40,000 - €55,000', description: 'Buscan un desarrollador salvavidas que pueda hacer de todo.', tags: ['React', 'Node.js', 'MongoDB'], }, ] return ( <div className="app"> <Header /> <main> <section className="jobs-container"> <h2>Trabajos Disponibles</h2> {/* Aquí renderizaremos los JobCard */} </section> </main> <Footer /> </div> )}
Creando el componente JobCard
Ahora vamos a crear el componente JobCard. Este componente recibirá props con la información de cada trabajo.
Crea un nuevo archivo src/components/JobCard.jsx:
function JobCard({ job }) { return ( <article className="job-card"> <header className="job-card-header"> <h3 className="job-title">{job.title}</h3> <p className="job-company">{job.company}</p> </header> <div className="job-card-body"> <p className="job-location">📍 {job.location}</p> <p className="job-salary">💰 {job.salary}</p> <p className="job-description">{job.description}</p> </div> <footer className="job-card-footer"> <span className="job-tags">{job.tags.join(', ')}</span> <button className="btn-apply">Aplicar</button> </footer> </article> )}export default JobCard
Simplificando el componente con la desestructuración
function JobCard({ job }) { // extraemos las propiedades del objeto job const { title, company, location, salary, description, tags } = job return ( <article className="job-card"> <header className="job-card-header"> <h3 className="job-title">{title}</h3> <p className="job-company">{company}</p> </header> <div className="job-card-body"> <p className="job-location">{location}</p> <p className="job-salary">{salary}</p> <p className="job-description">{description}</p> </div> <footer className="job-card-footer"> <span className="job-tags">{tags.join(', ')}</span> <button className="btn-apply">Aplicar</button> </footer> </article> )}
¿Qué hace este componente?
1. Recibe props
function JobCard({ job }) { // Este componente recibe un objeto 'job' como prop
Desestructuración de props: En lugar de escribir props.job.title, desestructuramos y usamos directamente job.title.
// ❌ Sin desestructuración (más verboso)function JobCard(props) { return <h3>{props.job.title}</h3>}// ✅ Con desestructuración (más limpio)function JobCard({ job }) { return <h3>{job.title}</h3>}
Ahora desestructuramos el objeto job en el componente JobCard.
function JobCard({ job }) { const { title } = job return <h3 className="job-title">{title}</h3>}
2. Renderiza la información del trabajo
<h3 className="job-title">{title}</h3><p className="job-company">{company}</p>
Usamos expresiones de JavaScript {title} para mostrar datos dinámicos.
Usando el componente en App
Ahora importa y usa el componente en App.jsx:
import Header from './components/Header'import Footer from './components/Footer'import JobCard from './components/JobCard'function App() { return ( <div className="app"> <Header /> <main> <section className="jobs-container"> <h2>Trabajos Disponibles (3)</h2> <div className="jobs-grid"> <JobCard job={{ id: 1, title: 'Frontend Developer', company: 'TechCorp', location: 'Madrid, España', salary: '€45,000 - €60,000', description: 'Estamos buscando un desarrollador frontend con experiencia en React.', tags: ['React', 'TypeScript', 'CSS'], }} /> <JobCard job={{ id: 2, title: 'Backend Developer', company: 'DataStack', location: 'Barcelona, España', salary: '€50,000 - €70,000', description: 'Desarrollador backend para trabajar con Node.js y bases de datos.', tags: ['Node.js', 'PostgreSQL', 'API'], }} /> <JobCard job={{ id: 3, title: 'Full Stack Developer', company: 'StartupX', location: 'Valencia, España', salary: '€40,000 - €55,000', description: 'Buscan un desarrollador salvavidas que pueda hacer de todo.', tags: ['React', 'Node.js', 'MongoDB'], }} /> </div> </section> </main> <Footer /> </div> )}export default App
¿Qué pasa aquí?
- Importamos el componente
JobCard - Creamos tres instancias del componente manualmente con sus respectivos datos
- Pasamos la prop
jobcon todos los datos de cada trabajo - Cada JobCard renderiza la información de su trabajo correspondiente
💡 Por ahora repetimos el componente manualmente. Más adelante en esta clase veremos cómo usar
.map()para automatizar esto y no tener que repetir el código tantas veces.
Componentización progresiva
Este es el proceso que hemos seguido:
Paso 1: Todo en App
function App() { // 500 líneas de HTML return <div>...todo el HTML...</div>}
Paso 2: Header y Footer
function App() { return ( <div> <Header /> {/* ← Separado */} ... contenido ... <Footer /> {/* ← Separado */} </div> )}
Paso 3: Crea un componente JobList
Crea un componente <JobList> que renderice la lista de trabajos. ¡Este es tu turno! Además, crea todos los componentes que consideres. Por ahora la lista la puedes renderizar a mano porque próximamente aprenderemos cómo usar .map() para renderizar listas.
¡Resumiendo que es gerundio!
En esta clase has aprendido:
- 🏷️ Props - Cómo pasar datos de un componente a otro
- 🔑 Prop
key- Obligatoria al renderizar listas - 📦 JobCard - Componente reutilizable para cada trabajo
- 📋 JobList - Componente que renderiza la lista de trabajos
- 🎯 Componentización - Separar en componentes más pequeños
- 💡 Desestructuración de props -
{ job }en lugar deprops.job
💡 Recuerda: Las props fluyen de padre a hijo. Usa props para hacer componentes reutilizables que puedan mostrar diferentes datos cada vez.
