Fecha publicación: 24 jun 2025

12. Añadiendo componentes React en cliente

Astro soporta integraciones de diferents librerías (React, PReact, Svelte, Vue, etc) y en este caso vamos a añadir un componente de React y ejecutarlo en cliente.

Para ello:

Instalamos un paquete oficial de Astro que nos permite integrar de React en nuestro proyecto:

npm install @astrojs/react

Agregamos React__ a la configuración de _Astro:

./astro.config.mjs

import { defineConfig, envField } from "astro/config";
+ import react from '@astrojs/react';

export default defineConfig({
+  integrations: [react()],
  env: {
    schema: {
      CONTENT_ISLAND_SECRET_TOKEN: envField.string({
        context: "server",
        access: "secret",
        optional: false,
        default: "INFORM_VALID_TOKEN",
      }),
    },
  },
});

Vamos ahora a crear un componente de React, que muestro un botón con un pulgar para arriba y un contador de likes.

Ojo, aquí lo importante es ver que el componente de React se integra, lo que es el contador de likes es solo un ejemplo tonto, de hecho vamos almacenar los likes en localStorage y sólo en una variable, así que todos los cursos tendrán el mismo número de likes.

¿Qué tenemos en este componente?

  • Un estado likes que guarda el número de likes.
  • Un useEffect que carga los likes desde localStorage al montar el componente.
  • Un manejador handleLike que incrementa el número de likes y los guarda en localStorage.
  • Un botón que muestra el número de likes y al hacer clic llama al manejador handleLike.

./src/components/like-button.component.tsx

import { useState, useEffect } from "react";

export const Like: React.FC = () => {
  const [likes, setLikes] = useState<number>(0);

  useEffect(() => {
    // Cargar los likes desde localStorage al montar el componente
    const storedLikes = localStorage.getItem("likes");
    if (storedLikes) {
      setLikes(parseInt(storedLikes, 10));
    }
  }, []);

  const handleLike = () => {
    const newLikes = likes + 1;
    setLikes(newLikes);
    localStorage.setItem("likes", newLikes.toString());
  };

  return (
    <button
      onClick={handleLike}
      style={{
        fontSize: "1.5rem",
        border: "none",
        background: "transparent",
        cursor: "pointer",
      }}
    >
      👍 {likes}
    </button>
  );
};

export default Like;

Y ahora vamos usarlo en las lecciones de los cursos, lo ponemos justo debajo del vídeo de la lección:

src/pages/training/[trainingSlug]/[lessonSlug]/index.astro

---
import Layout from "@/layouts/Layout.astro";
import { getTrainings } from "@/api";
import VideoComponent from "@/components/training/video.astro";
import LessonsComponent from "@/components/training/lessons-list.astro";
import LessonContentComponent from "@/components/training/lesson-content.astro";
+ import {Like} from "@/components/like-button.component";
<Layout title={`${training.title} - ${currentLesson?.title}`}>
  <div class="max-w-7xl mx-auto px-4 py-8">
    <h1 class="text-4xl font-bold mb-8 text-center">{training.title}</h1>

    <div class="grid md:grid-cols-12 gap-6">
      <div class="md:col-span-8">
        <VideoComponent
          videoUrl={currentLesson?.video ?? ""}
          title={currentLesson?.title ?? ""}
        />
+        <Like client:load />
      </div>

Fijate en un detalle importante, hemos añadido client:load al componente de React, esto indica a Astro que este componente debe ser cargado en el cliente, es decir, que se ejecutará en el navegador y no en el servidor, si quieres ver la diferencia, prueba a quitar el client:load y verás que el componente se renderiza, pero no se ejecuta en cliente: el número de likes se queda a cero y el botón no funciona al hacer clic, no incrementa el número de likes.

Si depuramos en el navegador podemos ver como podemos poner un breakpoint en el código de React (es código que se ejecuta en cliente).

En la próxima lección vamos a ver que son las Server Actions.