Newsletter para devsEntra
Aprende Astro framework

Componentes en Astro

Es el momento de trabajar de forma más profunda los componentes de Astro.

⚡️Este es el capítulo más importante del bootcamp.

Si conoces otros frameworks orientados a web verás muchas similitudes.

Si es la primera vez que ves algo así, estás de suerte, porque Astro lo hace MUY fácil.

👀 El Layout que vimos en pasos anteriores es también un componente.

🔍 Un componente es una unidad mínima de funcionalidad reutilizable. Una aplicación web es una unión de varios de estos componentes.

Componente estático

Aprovechemos el fragmento de código donde estamos colocando la foto, el título y la descripción.

Crea la nueva carpeta /src/components y un nuevo fichero dentro Hero.astro.

/src/components/Hero.astro
Copy

_23
---
_23
---
_23
<div class="container col-xxl-8 px-4 py-5">
_23
<div class="row flex-lg-row-reverse align-items-center g-5 py-5">
_23
<div class="col-10 col-sm-8 col-lg-6">
_23
<img
_23
src="https://placekitten.com/g/500/400"
_23
class="d-block mx-lg-auto img-fluid"
_23
alt="Flamante página de Astro"
_23
width="700"
_23
height="500"
_23
loading="lazy"
_23
/>
_23
</div>
_23
<div class="col-lg-6">
_23
<h1 class="display-5 fw-bold lh-1 mb-3">Mi primera Astro web</h1>
_23
<slot />
_23
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
_23
<a href="/about" class="btn btn-primary btn-lg px-4 me-md-2">Leer más</a>
_23
</div>
_23
</div>
_23
</div>
_23
</div>

Ahora cambia el index.astro y sustituye todo el contenido por el componente Hero.

/src/pages/index.astro
Copy

_10
---
_10
import Hero from "../components/Hero.astro";
_10
import SiteLayout from "../layouts/SiteLayout.astro";
_10
---
_10
_10
<SiteLayout>
_10
<div class="container col-xxl-8 px-4 py-5">
_10
<Hero/>
_10
</div>
_10
</SiteLayout>

👀 El componente funciona de forma similar a una etiqueta HTML. Como todavía no tenemos ningún elemento hijo (pronto sí, ya verás) la etiqueta puede abrirse y cerrarse con / en la misma etiqueta.

Añadimos props para hacerlo dinámico

Es claro que si queremos reutilizar el componente hay que dotarle de “vida”.

Usemos de nuevo los props para pasar atributos desde el padre (index.astro) al componente.

/src/components/Hero.astro
Copy

_30
---
_30
const {title, imageUrl, buttonText, buttonLink} = Astro.props
_30
---
_30
_30
<div class="row flex-lg-row-reverse align-items-center g-5 py-5">
_30
<div class="col-10 col-sm-8 col-lg-6">
_30
<img
_30
src={imageUrl}
_30
class="d-block mx-lg-auto img-fluid"
_30
alt="Flamante página de Astro"
_30
width="700"
_30
height="500"
_30
loading="lazy"
_30
/>
_30
</div>
_30
<div class="col-lg-6">
_30
<h1 class="display-5 fw-bold lh-1 mb-3">{title}</h1>
_30
<p class="lead">
_30
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
_30
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
_30
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
_30
aliquip ex ea commodo consequat.
_30
</p>
_30
<div class="d-grid gap-2 d-md-flex justify-content-md-start">
_30
<a href={buttonLink} class="btn btn-primary btn-lg px-4 me-md-2"
_30
>{buttonText}</a
_30
>
_30
</div>
_30
</div>
_30
</div>

⚡️Gracias al Atro.props podemos definir atributos variables. Hemos alterado el componente para que permita modificar título, la URL de la imagen y el enlace y texto del botón.

👀 Importante: Cuando el prop está entre etiquetas usamos la notación {buttonText} y cuando es el valor para un atributo hacemos lo mismo, pero eliminamos las comillas: href={buttonLink}

Ahora ajustemos el lugar donde llamamos al componente para asignarle los parámetros adecuados.

/src/pages/index.astro
Copy

_15
---
_15
import Hero from "../components/Hero.astro";
_15
import SiteLayout from "../layouts/SiteLayout.astro";
_15
---
_15
_15
<SiteLayout>
_15
<div class="container col-xxl-8 px-4 py-5">
_15
<Hero
_15
title="Mi primera Astro web"
_15
imageUrl="https://placekitten.com/g/500/400"
_15
buttonText="Leer más"
_15
buttonLink="/about"
_15
/>
_15
</div>
_15
</SiteLayout>

💪 Primer componente dinámico funcionando

Buenas prácticas: Tipos y valores

Vamos a añadir aquí un concepto de TypeScript.

🎧 Podcast: WR 257: TypeScript puede ser tu lenguaje para SIEMPRE

😱 No te asustes, es solo para sacarle partido a la potencia de Astro y su uso interno del lenguaje TypeScript para dar más poder y control al developer… ¡a ti!

Al inicio del componente Hero añadimos esto:

/src/components/Hero.astro
Copy

_10
---
_10
interface Props {
_10
title: string,
_10
imageUrl: string,
_10
buttonText: string,
_10
buttonLink: string
_10
}
_10
const { title, imageUrl, buttonText, buttonLink } = Astro.props;
_10
---

👀 El interface Props es una declaración de variables y tipos. Astro a partir de este momento controlará que los 4 props que hemos definido tengan el tipo de string (cadena de texto) y que sean obligatorios.

Si alguno de los props fuera un número podríamos utilizar number en vez de string. Pero, por ahora, tranquilo, no es esencial profundizar en esto.

💦 Vete a index.astro y en la inserción del componente <Hero> prueba a eliminar algún atributo como por ejemplo title.

💪 ¿Ves lo que pasa? Aparece en rojo y te indica que hay un error. Eso es gracias al interface.

💣 Si te encuentras con algunos problemas debidos a TypeScript puedes reducir los requisitos que tiene que cumplir tu código cambiando el contenido del fichero tsconfig.json en tu carpeta raíz.

/tsconfig.json
Copy

_10
{
_10
"extends": "astro/tsconfigs/base"
_10
}

Props opcionales

Acabamos añadiendo una opción más a nuestro interface Props. La capacidad de que alguno de nuestros props sean opcionales.

/src/components/Hero.astro
Copy

_10
---
_10
interface Props {
_10
title: string;
_10
imageUrl: string;
_10
buttonText?: string;
_10
buttonLink?: string;
_10
}
_10
const { title, imageUrl, buttonText, buttonLink } = Astro.props;
_10
---

👀 Añadiendo un ? TypeScript y, por tanto Astro, entienden que esos dos props son ahora opcionales.

🔍 Dejamos para un poco más adelante cómo sacar partido a esos props opciones, lo haremos cuando veamos la sintaxis JSX.

💦 ¿Te animas a reutilizar el componente Hero en about.astro? Es muy fácil. Recuerda importar el componente en la parte encerrada entre las tres líneas ---.

💪 Componentes listos, o casi ;)

⚡️ Pon a prueba lo que has aprendido

1. ¿Qué es un componente en Astro?
2. ¿Cómo se pueden hacer componentes dinámicos en Astro?
3. ¿Qué es 'interface Props' en el contexto de Astro?
4. ¿Cómo se indica que un prop es opcional en Astro?

Este contenido llega a ti gracias a la Comunidad de suscriptores de Web Reactiva