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.