Desatando los Componentes del Servidor React: Una Inmersión Profunda en el Desarrollo Web de la Próxima Generación

Rate this content
Bookmark

¡Prepárate para potenciar tus habilidades de desarrollo web con los Componentes del Servidor React! En esta inmersiva masterclass de 3 horas, desbloquearemos el potencial completo de esta tecnología revolucionaria y exploraremos cómo está transformando la forma en que los desarrolladores construyen aplicaciones web rápidas y eficientes.


Únete a nosotros mientras nos adentramos en el emocionante mundo de los Componentes del Servidor React, que combinan sin problemas el renderizado del lado del servidor con la interactividad del lado del cliente para un rendimiento y una experiencia de usuario inigualables. Obtendrás experiencia práctica a través de ejercicios prácticos, ejemplos del mundo real y orientación experta sobre cómo aprovechar el poder de los Componentes del Servidor en tus propios proyectos.


A lo largo de la masterclass, cubriremos temas esenciales, incluyendo:

- Entender las diferencias entre los Componentes del Servidor y del Cliente

- Implementar Componentes del Servidor para optimizar la obtención de datos y reducir el tamaño del paquete JavaScript

- Integrar Componentes del Servidor y del Cliente para una experiencia de usuario fluida

- Estrategias para pasar datos efectivamente entre componentes y gestionar el estado

- Consejos y mejores prácticas para maximizar los beneficios de rendimiento de los Componentes del Servidor React

149 min
13 Dec, 2023

AI Generated Video Summary

Los Componentes del Servidor React permiten el renderizado del lado del servidor y mejoran el rendimiento al reducir el código enviado al navegador. Habilitan operaciones asíncronas en el servidor, como consultas a la base de datos, sin endpoints separados. Next.js es un servidor adecuado para los Componentes del Servidor React y proporciona una mejor seguridad de tipo al consultar directamente la base de datos. Next.js también ofrece una caché de enrutador que se puede controlar para asegurar que los datos actualizados se reflejen inmediatamente en la aplicación. Los Componentes del Servidor React se pueden utilizar con APIs específicas de Next para actualizar la UI y simplificar el manejo de formularios eliminando la necesidad de JavaScript en el cliente.

1. Introducción a los Componentes del Servidor React

Short description:

¡Bienvenidos a React Server Components Unleashed! Soy Maurice de Beyer, un instructor de desarrollo independiente. En esta masterclass, exploraremos el futuro de React y nos sumergiremos en los Componentes del Servidor React. Si tienen alguna pregunta, no duden en contactarme en Twitter o por correo electrónico.

Bienvenidos a todos a esta masterclass, React Server Components Unleashed. Vamos a hacer una deep dive en el futuro de React. Vamos a empezar de manera relativamente fácil porque asumo que todos ustedes tienen experiencia con React. Si no es así, háganmelo saber porque podría tener que explicar algunas cosas más que esperaba que todos supieran.

Pero no espero que la gente esté realmente familiarizada con los React Server Components. Supongo que han oído hablar de ellos y por eso se inscribieron en esta masterclass. Eso suena interesante. ¿Qué es eso, etc.?

Entonces, ¿quién soy yo? Mi nombre es Maurice de Beyer, también conocido como el solucionador de problemas. Entre otras cosas, soy MVP de Microsoft, lo que no significa que trabaje para Microsoft, sino que simplemente hago marketing para ellos. Muchas presentaciones, masterclasses, cosas así. Instructor de Desarrollo Independiente actualmente trabajando para algún día en una startup de FinTech en los Países Bajos. Estoy en Twitter. Tengo sitios web como casi todos. No es que haya mucho contenido interesante allí, pero si quieren, pueden echarle un vistazo. Tengo una dirección de correo electrónico, así que si tienen preguntas más tarde sobre el material de este curso, no duden en contactarme en Twitter o por correo electrónico para hacerme preguntas.

2. Resumen de la Masterclass

Short description:

Cubriremos los Componentes del Servidor React, transformando los Componentes React del lado del cliente en componentes del lado del servidor, consultas y actualizaciones de la base de datos, suspense y streaming, composición de componentes y Acciones del Servidor React. Esta masterclass interactiva fomenta el aprendizaje práctico para obtener los mejores resultados.

Entonces, ¿qué vamos a cubrir? Bueno, vamos a empezar con ¿qué son los React Server Components y por qué debería importarte? Vamos a echar un vistazo a Next.js y al Escritor de la App Next.js porque, como sugiere el nombre, React Server Components. Necesitamos una parte del servidor aquí. Ya no es solo en el cliente en el navegador. Y luego vamos a ver cómo podemos convertir los Componentes React existentes del lado del cliente en componentes del lado del servidor. Cómo podemos hacer consultas a la database, actualizaciones de la database, cosas así, directamente dentro de tus componentes, lo cual es bastante interesante.

Veremos cómo funciona esto con suspense y streaming bajo el capó. Haremos una especie de deep dive en cómo se renderizan ciertos componentes, dónde se renderizan, cómo puedes componer esos componentes juntos para obtener algunos resultados específicos. Y echaremos un vistazo a algo que suena completamente diferente, las Acciones del Servidor React, pero que en realidad forman parte de la especificación de los React Server Components. Especialmente cuando empiezas a hacer forms, data entry forms, las Acciones del Servidor React son una forma realmente interesante de hacerlo. Pero en realidad son más generales que eso, no son solo para data entry forms, hay mucho más que puedes hacer con eso.

También he convertido este curso, o debería decir esta masterclass, en un curso más amplio donde profundizo más en el material, cubro material, simplemente no tengo tiempo para hacerlo en esta masterclass. Así que solo una recomendación general, esta es una masterclass muy interactiva. Voy a hacer demostraciones de cómo hacer cosas con los React Server Components, y la configuración básica es para que tú hagas lo mismo. Puedes simplemente verme hacerlo y eso es todo. Eso está bien si quieres. Puedes copiar y pegar todos los códigos de GitHub si quieres, eso también está bien si quieres. Pero sacarás más provecho de esta masterclass si realmente escribes el código, cometes errores de tipeo, cometes errores, ves los mensajes de error, etc. Hacer es la mejor forma de aprender. Solo mirando, recogerás tips y quizás te resultará familiar dentro de un mes. Si copias y pegas durará un poco más, pero no mucho más. Escribir es simplemente la mejor forma de aprender, hacer cosas.

3. Prerrequisitos para los Componentes del Servidor React

Short description:

Para comenzar, asegúrate de tener Node 16 o posterior y Git instalados. Usa npm para instalar los paquetes requeridos. Yarn y pnpm también son gestores de paquetes aceptables. Comprueba tus versiones de Node y npm usando 'node -v' y 'npm -v'.

Ahora tenemos algunos prerrequisitos con los que supongo que todos están bien, porque supongo que todos están usando React. Necesitarás Node. Node 16 o posterior está bien. La captura de pantalla aquí tiene Node 18. Creo que tengo Node 20 y algo en mi máquina ahora mismo, actualizado desde que creé la captura de pantalla. Necesitaremos Git, pero solo para clonar el repositorio. Así que no mucho uso de Git. Y por supuesto necesitaremos npm para instalar los paquetes requeridos de npm, que no están incluidos con el repositorio. Si tienes yarn o pnpm, son gestores de paquetes perfectamente aceptables. Pero aún así te recomendaría que uses npm para instalar porque hay un archivo package.log.json que npm usa. Y de esa manera obtienes exactamente la misma versión de paquetes que estoy usando. Así que tengo una pequeña ventana de terminal abierta. Si quieres comprobar, podrías hacer algo como node-v o —version. Y te dirá, estoy en node 20.9.0. Así que Node 16 o posterior va a estar bien. Lo mismo con npm. Tengo como, ¿qué es? Dash v. Npm 10.2.4, pero como npm 9 o 8, cualquiera de eso estará bien.

4. Configuración de la Masterclass y Clonación del Repositorio

Short description:

Se han compartido dos enlaces importantes en la ventana de chat: uno al repositorio que contiene todo el código, y otro a un PDF con todos los materiales de la masterclass. El repositorio contiene imágenes con cambios de código, cada una vinculada al commit específico donde se realizó el cambio. El repositorio inicial es una aplicación Next.js, y lo convertiremos para usar Componentes de Servidor React. La configuración básica incluye TypeScript, ESLint, Tailwind CSS, y el enrutador de la aplicación, que es necesario para los Componentes de Servidor React. La aplicación también incluye componentes Shad.CM para una interfaz de usuario más agradable. Cada paso en la masterclass es un commit separado en el repositorio de GitHub. Jean-Luc Picard te indicará ocasionalmente que realices ciertas tareas. Se utilizarán salas de trabajo en grupo para el trabajo en grupo, y puedes invitarme para asistencia. La primera tarea es clonar el repositorio de GitHub.

Hay dos enlaces importantes, que también se compartieron en la ventana de chat. El primero es un enlace al repositorio. GitHub.com, mi nombre de usuario es MauriceDB. Y luego react-berlin-2023-ws. Permíteme acercar un poco eso. Esto contiene todo el código. Lo clonaremos en un minuto. El otro enlace está aquí, un poco puntiagudo. Y luego con la misma masterclass react-berlin-2023-ws. Esto contiene un PDF con todos los materiales. Y dependiendo de tu navegador, lo descargará o, como hace Chrome, simplemente lo mostrará en línea. Ahora, te recomiendo encarecidamente que tengas a mano este PDF porque así, tienes los enlaces aquí. Pero la mayoría de estas imágenes, permíteme desplazarme un poco más. ¿Dónde, dónde, dónde? Aquí, verás imágenes como esta con los cambios de código que haremos. Todos estos son enlaces. Si haces clic en el enlace, te llevará a, bueno, en este caso, los componentes. En la mayoría de los casos, te llevará al commit específico donde se realizó ese cambio. Así puedes ver exactamente qué se hizo. Permíteme encontrar otro, que te lleve a un commit. Abre alguna imagen aleatoria. Luego ves que, para este paso, básicamente, agregamos este componente, hicimos estos cambios aquí, etc. Cada paso lo confirmé como un commit separado y está vinculado en GitHub. Conveniente. También puedo escanear el código QR. Dejaré esto arriba por un minuto.

Ahora, el repositorio inicial es básicamente una aplicación Next.js, que vamos a usar. Y la rama principal contiene todo el código completado. Así que también tienes todo el código en tu máquina. Hay una rama 00start, que es en realidad el lugar de inicio desde donde comenzaremos y convertiremos esa aplicación, que es una aplicación Next puramente del lado del cliente. Y la convertiremos para usar los React Server Components. La configuración básica está ahí, pero aún no es un Componente de Servidor React. Así que no necesitamos hacer esto, pero solo para mostrarte lo que hice para crear esta aplicación, creé la aplicación Next con el Create Next app. Seleccioné TypeScript porque soy un fanático de TypeScript. No hay nada con los React Server Components que requiera TypeScript, pero me gusta usarlo. Habilité ESLint, aunque realmente no hice mucho con eso. Es solo una elección predeterminada. Uso Tailwind CSS, que también me gusta bastante. De nuevo, no es necesario, pero así es como está configurado aquí. Estamos usando la carpeta SRC, también opcional, pero útil. Y una cosa importante es esta. Te hacen una pregunta si quieres configurarlo. ¿Quieres usar el enrutador de la aplicación? Sí, no, se recomienda. Pero para usar los React Server Components, no solo se recomienda. Es realmente necesario. Si dices que no a esto, obtendrás la carpeta de páginas tradicional en Next.js y la carpeta de páginas no admite los React Server Components. Así que asegúrate de que esto esté configurado en sí. Hay un alias para las importaciones, que ayuda un poco, pero no es tan importante. Así que eso es lo que hice para crear la aplicación básica. Luego instalé Shad.CM para obtener algunos componentes agradables. Nada difícil allí. Añadí un montón de los propios componentes de Shad.CM, que se utilizan. De nuevo, nada realmente necesario, solo para hacer la interfaz de usuario un poco más agradable y fácil. Como mencioné, todos los diferentes pasos son diferentes commits en el repositorio de GitHub. Así que esto te llevará a esa lista de comandos si quieres verlos. Y luego verás a este caballero combinado bastante a menudo, Jean-Luc Picard, que es famoso por Engage. En este caso, no tienes que hacer algo, pero en otros casos, cuando él aparece, básicamente es tu señal para hacer algo. Acabo de demostrar cómo hacer algo como crear un React Server Components o hacer alguna consulta asíncrona en él o algo así. Y básicamente es tu turno de hacer eso. Y asegúrate de que la técnica y todo lo que es importante allí está claro. Estaré usando una función de Zoom, que son las salas de trabajo en grupo, donde básicamente divido el grupo en muchas pequeñas salas. Puedes trabajar juntos en una de esas salas. Haz preguntas sobre cosas a los demás, es un poco más fácil cuando estás solo con tres o cuatro personas, pero también puedes invitarme si te quedas atascado en algún lugar. Así que puedes invitarme a esa sala de trabajo en grupo y me uniré para explicar algo, lo cual es un poco más fácil en una sala de trabajo en grupo con tres o cuatro personas que en todo el grupo con más de 30 personas. Ahora, lo primero que necesitamos hacer, que en realidad voy a hacer, es clonar este repositorio de GitHub. Así que en realidad vamos al repositorio. ¿Dónde está? Códigos aquí. Copia esa URL, ve al terminal. Es clonar, pasa esa URL. Y estoy usando HTTPS aquí, pero también puedes usar la versión Git. Así que hemos clonado el repositorio.

5. Configuración del Proyecto y Exploración del Código

Short description:

Voy a cd en el directorio del proyecto e instalaré los paquetes npm. Estamos usando Prisma para los datos, y hay una migración para crear y poblar la base de datos. La estructura del código incluye carpetas para Next.js, Prisma y los componentos de la aplicación. La pantalla de inicio muestra películas mejor valoradas, géneros y formularios de edición. La página del servidor o clientes explora la composición de componentes. La sección de películas permite agregar a un carrito de compras y realizar el pago. La pantalla de detalles permite la edición y el restablecimiento de datos. El código sigue un estilo React tradicional sin las capacidades de Next.js. Asegúrate de revisar la rama 00-start.

Voy a cd en eso y haré una instalación de npm. Así que eso va a instalar los paquetes de npm. Recuerda, se sugiere usar npm, no yarn o pnpm. No tengo nada en contra de esos, pero no hay archivos de registro para esos. Así que en el caso, podrías obtener nuevas versiones de componentes de Next y las cosas podrían funcionar ligeramente diferente.

Ahora deberías ver mensajes como este. Estoy usando Prisma aquí para los datos reales que vamos a usar. Hay una migración de Prisma, que crea la base de datos desde cero y la llena con datos. Así que ese es este comando tsnode sheet, que pone los datos allí. Si no ves esto, o hay un error, terminarás sin ningún dato, lo que hará un poco más difícil hacer cosas.

Ahora, puedo abrir esto en VS Code. Si estás familiarizado con la aplicación Next, probablemente hayas visto esto, como tenemos una configuración estándar de Next aquí, etc. Mayormente no cambié esos, como hubo un pequeño cambio aquí para las imágenes. Estoy usando los datos de la base de datos de películas de allí y las imágenes de allí, que uso frecuentemente con las masterclass. Hay una carpeta de Prisma aquí con las cosas de la base de datos. Realmente no vamos a tocar eso, pero está allí si quieres. Y no, no quiero actualizar Visual Studio Code ahora. Creo que acaba de tener una actualización, pero.

Más importante, hay una carpeta src. Hay una carpeta de aplicación porque estamos usando el enrutador de la aplicación. Y aquí, encontrarás cosas como esta página, que es básicamente una ruta. Así que esta página en la carpeta de la aplicación raíz es la página de inicio, como si vas al sitio web, y luego hay una para la página de películas aquí, y hay una para una película específica, como esa. Antes de empezar realmente, voy a cambiar a una rama diferente, la rama 00-start. Y luego voy a hacer un npm run dev, o normalmente lo hago a través de Visual Studio Code de esta manera. Así que tengo la ventana de la consola aquí donde está corriendo. Y luego si voy aquí, localhost puerto 3000, debería ver la aplicación aparecer. Y ahí está.

Así que la pantalla de inicio acaba de tener una actualización, y ahí está. Así que la pantalla de inicio solo tiene una bonita imagen. Hay una lista de películas mejor valoradas aquí, al menos una lista corta, solo algunos datos para trabajar. Puedes ver todas ellas así, o puedes verlas, filtrarlas por categoría, como las de aventura, o thriller, o como, ¿qué es? Familia. Supongo que no hay tantas películas familiares mejor valoradas. Hay una lista de géneros aquí. Cada uno de estos tiene un pequeño formulario de edición. Actualmente, estos no están funcionando. Como puedes editar allí. Puedes hacer clic en Guardar Cambios, pero nada se guardará. Volveremos a eso más tarde. Hay una página de servidor o clientes aquí, que usaremos para explorar cómo los componentes pueden ser compuestos juntos. Y dentro de las películas, hay un poco de funcionalidad. Puedes agregar películas al carrito de compras, y luego este botón se ilumina. Puedes hacer un pago. Necesitas pasar un nombre, y luego el número de cuenta, que tiene que ser de cuatro caracteres de largo. Y luego puedes hacer clic en OK, y luego obtenemos este mensaje aquí, Pago Completado. Y en la consola, en realidad tuve un mensaje aquí sobre las películas que pagué. También hay una pantalla de detalles, que es, de nuevo, un formulario de edición, así que puedo hacer cambios. Y aquí realmente puedo hacer cambios como me gusta El Padrino Parte 1. Envío esto, y si vuelvo a la lista de películas, vemos El Padrino 1. Realmente cambiamos eso de nuevo, o en realidad déjame hacer eso de una manera ligeramente diferente. Vuelve aquí. Porque otra cosa útil para darse cuenta es que tengo esto, ¿dónde está?, allá, comando Prisma Seed. Así que ese es este comando aquí. Y si lo ejecutas, ya sea desde el comando, o como estoy haciendo ahora, normalmente lo ejecuto desde aquí, ejecutará la acción Prisma Seed de nuevo. Así que básicamente... Bueno, no recrea la base de datos, pero restablecerá los datos en la base de datos. Así que si vuelvo aquí y refresco esto, tengo El Padrino sin ningún cambio. Así que esta es básicamente la aplicación con la que vamos a trabajar. El código actualmente es bastante tradicional. Solo para darte una pequeña vista previa allí. No necesitas hacer esto. Como la lista de películas, básicamente tiene una forma muy tradicional. Utiliza los estados de uso para rastrear el estado. Utiliza el usuario de fábrica con una búsqueda aquí para cargar los datos, los datos de la película. Hay un punto final aquí para consultar esas películas. Así que una aplicación de estilo React muy tradicional. Ni siquiera utiliza las capacidades de Next.js de GetServerSideProps o GetServerSideProps. O GetStaticProps o cualquiera de esas cosas. Así que volvamos a las diapositivas. Así que los paquetes de npm acaban de ser instalados. Y luego no olvides esto para revisar la rama 00start.

6. Entendiendo los Componentes del Servidor de React

Short description:

Los Componentos del Servidor de React se ejecutan solo en el servidor, no en el navegador. Requieren que React divida los componentes en componentes del servidor y del cliente. Los componentes del servidor se renderizan en el servidor y no se vuelven a renderizar en el navegador, mientras que los componentes del cliente se renderizan en el cliente y pueden volver a renderizarse. Los componentes del servidor de React permiten operaciones asíncronas en el servidor, como consultas a la base de datos, sin la necesidad de puntos finales separados. Esto mejora la seguridad ya que los datos sensibles no se envían al navegador.

Porque si no lo haces, estarás en la rama principal, que ya contiene todo el código que necesitas. Lo que hace un poco difícil hacer cosas. Así que npm run dev ejecuta Next.js en entornos de desarrollo. Así que recompilará y construirá todos los cambios y los servirá. Y luego cuando vayas al navegador en el host local para 3000, deberías ver esta imagen y poder hacer clic a través de la aplicación, como acabo de hacer.

Así que con eso, es hora de hacer esto. Para el primer ejercicio, asegúrate de que puedes clonar el repositorio, revisar la rama 00start, asegurarte de que la aplicación se ejecuta y es funcional, igual que para mí.

Antes de que realmente nos ocupemos de los React Server Components, demos un paso atrás. ¿Y qué son los React Server Components, y hablemos de eso. Porque React Server Components sugiere con el nombre que hay un servidor involucrado. Y resulta que no es solo una sugerencia errónea, eso es realmente el caso. Pero tradicionalmente, React era este marco del lado del cliente. Potencialmente solo tendrías un servidor de archivos estáticos muy simple, cargarías JavaScript, y el navegador realmente renderizaría esos componentes y harían algo. No había realmente un servidor involucrado. Ahora con Next o Remix, podrías tener un servidor involucrado y hacer la renderización del lado del servidor. Pero la renderización del lado del servidor es básicamente renderizar los componentes en el servidor, luego enviar eso como HTML al navegador, y también enviar todos los componentes al navegador y ejecutarlos allí de nuevo. Y con los React Server Components, eso no es el caso. Los React Server Components solo se ejecutan en el servidor. Nunca se ejecutan en el navegador. Así que eso es bastante diferente.

Ahora, si lo miras, tengo un esquema realmente simple de una aplicación aquí. Tenemos una aplicación que renderiza un montón de componentes como una barra de navegación, una lista de películas, o un detalle de película, dependiendo de tu ruta, y con la lista de películas hay una serie de tarjetas de películas, y podrías ser capaz de calificar una película allí con un botón. Y tradicionalmente, serían React Components, y todo eso se renderizaría en el navegador. El servidor básicamente no hacía nada allí. Ahora, tradicionalmente, también teníamos la renderización del lado del servidor. Y si usas algo como Next o Remix, o tenías tu propia configuración de renderización del lado del servidor, podrías tener algo como esto donde todo eso se renderizaría en el servidor, y luego enviaría todo eso como HTML al cliente. Así que el cliente vería la página bien terminada antes. Pero todo el código del componente también se enviaría al cliente, y el cliente básicamente volvería a renderizar toda la aplicación y haría, bueno, cosas como los controladores de clic de eventos activos, empezaría a usar eventos de uso que no se ejecutarían en el servidor con la renderización del lado del servidor y cosas así. Así que básicamente todo sucede dos veces, o casi todo sucede dos veces. El servidor omitiría algunas partes, y el cliente siempre haría todo. Con los React server components, eso es un poco diferente.

Ahora la aplicación, la lista de películas, las tarjetas de películas, la navegación, los detalles de la película, etc., son componentes del servidor. Se renderizan en el servidor, pero no en el navegador. En el navegador, obtienes el resultado de lo que se renderiza allí, y eso se convierte en el modelo de objetos de documento del navegador. Así que las cosas que ves en la ventana del navegador, los divs, los spans, los botones, etc. Algunos componentes que requieren interactividad, como un editor de películas, pero quizás un botón de calificación de películas, algo así, que es un controlador de clic. Serían marcados como componentes del cliente. Y aunque estés usando los React server components, esos no se renderizan en el servidor. Siempre se renderizan en el servidor. Siempre se renderizan solo en el cliente. Eso significa que React tiene que hacer mucho más. En primer lugar, tiene que empezar a hacer cosas en el servidor, lo que nunca hizo, pero también significa que tiene que empezar a dividir cosas. Bueno, algunos de los componentes se renderizan en el servidor, y el código nunca se envía al navegador en absoluto. Nunca se vuelven a renderizar en el navegador. Así que en el navegador, son un poco estáticos. Otros componentes se renderizan en el cliente. Necesitan como tal vez un controlador de clic de botón o alguna otra browser API, o tal vez un efecto de uso o un estado de uso. Serán capaces de volver a renderizar o hacer más cosas allí. Y no pueden correr en el servidor. Siempre se renderizarán en el cliente. React tiene que dividir esos, tratarlos de manera diferente, y en el cliente en el navegador, en realidad combinar los resultados de la acción del servidor con la acción del cliente para darte la UI que quieres. Eso significa que React tiene que ser más inteligente.

Ahora, si solo tenemos la misma API que teníamos antes, no tendría mucho sentido, porque acabo de mencionar que una de las cosas que no puedes hacer en un React server component es usar estado y usar efecto. No puedes cambiar el estado para volver a renderizar algo porque esos componentes solo se renderizan una vez. Tener un efecto de uso, si no puedes cambiar el estado allí, no hace mucho. Así que tiene que haber algo que haga que todo esto valga la pena. Y el hecho es que los componentes del cliente son solo funciones simples. Bueno, tal vez no sean simples, pero son funciones relativamente sencillas. Se llaman, devuelven un objeto DOM virtual con lo que debería parecer el DOM, y eso es todo. Si necesitan hacer algo asíncrono, tienen que engancharse a usar efecto, etc., para hacer ese tipo de cosas. Bueno, con los componentes del servidor, puedes hacer que ese React component en sí sea una función asíncrona, y puedes empezar a usar await allí. Así que en un React server component, puedo hacer await a algún tipo de fetch, ir y hacer alguna consulta RESTful. Pero como se ejecuta en el servidor, también podría hacer una consulta a la database. Podría hacer un prisma.movies.findMany y encontrar todas las películas en la database y ordenar y filtrar y todas esas cosas que antes no podías hacer dentro de los React components. Anteriormente, la forma de hacer eso era crear un punto final RESTful o tal vez un punto final GraphQL, y luego hacer que el cliente consulte en eso usando use effect y fetch, y luego básicamente en el servidor, consultar los data, serializar eso a JSON, enviar eso de vuelta al navegador. El navegador entonces decidiría, bien, ahora tengo algún estado, volveré a renderizar todos los componentes, y actualizaré. Todo eso se vuelve mucho más directo ahora. Y efectos secundarios agradables. Esos componentes son mucho más seguros. Su código no se envía al navegador, así que cualquier cosa que pongas allí nunca se filtra, por así decirlo, a los clientes, como puedes poner nombres de usuario contraseñas allí.

7. Entendiendo los Componentes del Servidor de React (Cont.)

Short description:

Los Componentes del Servidor de React permiten la renderización en el servidor, reduciendo el código enviado al navegador y mejorando el rendimiento. Se recomienda TypeScript 5.1 o posterior para usar los Componentes del Servidor de React. La directiva use Client se utiliza para marcar los componentes para la renderización en el lado del cliente. Los componentes que utilizan estado, efectos secundarios, hooks o APIs del navegador deben ser marcados como componentes del cliente. Convertir un componente del cliente a un componente del servidor a menudo requiere cambios mínimos, como eliminar la directiva use Client y el código relacionado con el estado.

Como, no lo haría, pero puedes. Puedes poner claves de API para acceder a recursos allí. Eso está perfectamente bien. No va al navegador. También significa que el paquete real que sí va al navegador se vuelve mucho más pequeño, porque si la mitad de tus componentes nunca se envían al navegador, entonces eso es mucho menos código. Y presumiblemente no es solo el código que escribes, también son las bibliotecas que usan. Bueno, si usas todas esas bibliotecas solo en el servidor, bueno, eso significa que el cliente tiene que hacer mucho menos carga, mucho menos análisis, mucho menos renderización, y es mucho más rápido.

Si quieres usar TypeScript con los React Server components, eso no es un problema, pero solo asegúrate de que tienes al menos TypeScript 5.1. Estamos en 5.3 algo en este momento. No estoy seguro exactamente de la versión actual, pero es relativamente, o ya ha pasado 5.3. Así que si creas un nuevo proyecto, eso no va a ser un problema en absoluto. Pero si tienes una aplicación existente, vas a convertir a una aplicación basada en componentes del servidor de React. Entonces asegúrate de que no estás usando una versión muy antigua de TypeScript, porque TypeScript en aquel entonces no consideraba un componente de React para ser asíncrono, y si es algo que es asíncrono y usa await, TypeScript no lo compilará. Realmente se ejecutará, pero simplemente no se compilará.

Ahora, ¿cómo se ve un componente del servidor de React? Tal vez algo como esto. En realidad, en muchos casos no puedes decirlo. En este caso, puedo decir que este es un componente del servidor, porque por un lado, es un componente asíncrono aquí, y el otro es, aquí, estoy haciendo una llamada a Prisma. Así que voy a usar el ORM de Prisma para entrar en una database y encontrar, en este caso, una lista de géneros. Bueno, Prisma es orientado a database. Es un ORM de database, así que eso no va a funcionar en el navegador. Así que eso me dice que este es un componente del servidor de React. Los componentes del cliente no pueden ser asíncronos, así que eso es una pista, pero incluso si esto no fuera asíncrono, y no estuviera haciendo la consulta de Prisma, esto podría ser un componente del servidor. Hay muchos casos en los que es realmente difícil de decir, y es más un efecto secundario de otras cosas, pero no hay nada aquí que diga que esto debe ser un componente del servidor. Entonces, ¿cómo sabe React la diferencia entre un componente del cliente y un componente del servidor? Bueno, con los componentes del cliente, usamos esta directiva, use Client. Esto básicamente le dice a React que este componente debe renderizarse en el cliente. Resulta ser un poco más matizado que eso, pero asegurará que este cliente específico siempre se renderice en el cliente. Ahora, inicialmente encontré esto un poco extraño. Estamos hablando de los componentes del servidor de React, que es el nuevo estándar, pero no estamos marcando los componentes del servidor como componentes del servidor. En cambio, estamos marcando los componentes del cliente como componentes del cliente. Y como mostraré más tarde, la razón de esto es que use Client en realidad no dice que este es un componente del cliente, sino que este es un límite de componente del cliente. Podrías tener otro componente que se renderiza desde este componente, que no tiene use Client, pero porque se renderiza desde otro componente del cliente, también es un componente del cliente. Y ese mismo componente podría ser renderizado desde un componente del servidor, y porque ese es un componente del servidor, también se renderizaría como un componente del servidor. Así que es más como, ¿cómo se están renderizando las cosas por quién? Y el use Client realmente es el límite de, bien, aquí cambiamos de la renderización del servidor a la renderización del cliente.

Ahora, ¿qué tipo de componentes necesitan ser componentes del cliente? Ya mencioné una serie de ejemplos. Es básicamente todo lo que usa Estado, que usa Efectos secundarios. La regla simple es que cada componente que usa un hook, que no es 100% cierto, pero para una regla general, eso está perfectamente bien porque tendrás muy pocos hooks, que no usan Efectos secundarios, no usan Estados, o APIs del lado del cliente. Como en cualquier lugar donde uses APIs del navegador, necesita ser un componente del cliente, use Client. Si usas contexto, necesita ser un componente del cliente. Así que muchos de esos casos necesitan ser componentes del cliente. Así que todos ellos necesitarán tener una directiva Use Client.

Entonces, ¿qué se necesita para convertir realmente un componente del cliente de React en un componente del servidor? Bueno, en muchos casos, no mucho. Permíteme ir al código fuente de la aplicación por el momento. Y ahora mismo, si miro la lista de películas, es este componente. Así que esa es básicamente esta página, o por esa materia, cualquiera de estas páginas. Solo voy a quedarme aquí. Utiliza un componente muy tradicional, que es RenderTestedPage. Tiene un UseState allí, UseEffect. Así que como dije, eso debería ser un componente del cliente. Y el hecho de que si desplazo hasta la parte superior aquí, dice aquí, Use Client. Así que eso hace que esto sea un componente del cliente. Y todo esto solo se ejecuta en el navegador. Y digo solo ejecutado en el navegador porque la renderización del lado del servidor, eso no es del todo cierto. Pero si ignoras la renderización del lado del servidor por un momento, lo que Next sí hace, sería completamente cierto. Ahora puedo hacer esto un componente del cliente. Lo siento, un componente del servidor eliminando ese Use Client. Pero todavía tengo UseState aquí, tengo UseEffect aquí. Así que si lo que acabo de decir era cierto, esto debería fallar. Y de hecho, si voy al navegador ahora, dice, está bien, hay cosas aquí como UseState, así que deberíamos agregar ese Use Client allí. Así que si vuelvo a poner ese Use Client, mi error desaparece y la página se vuelve a renderizar. Pero si miro la funcionalidad aquí, miro el código fuente, básicamente obtiene un montón de películas, las mapea, crea tarjetas de películas para esas películas. Así que no hay interactividad aquí, solo está esta búsqueda de data. Y debería ser capaz de hacer eso igual de bien en el servidor mismo. Así que vamos a convertir esto en el componente del servidor. Deshazte del estado. Deshazte del UseEffect, no queremos nada de esto. Estamos usando await aquí, así que esta función debería ser async. Esto necesita ser tipado. De lo contrario, no sabe lo que es la película. Que es una de las desventajas de hacer una llamada fetch, como JSON solo devuelve una promesa de cualquier. No sabe nada sobre la tipificación.

8. Convirtiendo el Componente del Carrito de Compras

Short description:

El componente del carrito de compras utiliza un hook y tiene un botón con un evento onClick, lo que lo convierte en un componente del cliente. Para convertirlo, añade la directiva useClient en la parte superior del archivo, por encima de las importaciones.

Pero ahora, todo parece estar bien. Si vuelvo al navegador, obtendré un error. Aunque se queja de un componente muy diferente ahora, un carrito de compras. Si echo un vistazo a ese carrito de películas, verás que esto utiliza un nuevo carrito de compras. Así que esto utiliza un hook. Y como en casi todos los casos, los hooks significan que algo tiene que ser un componente del cliente. Pero también tengo un botón aquí con un onClick, y eso definitivamente lo convierte en un componente del cliente. Así que vamos a convertir esto en un componente del cliente añadiendo useClient. Ahora, si añades useClient para indicar que esto es un componente del cliente, tiene que estar en la parte superior del nivel del archivo por encima de tus importaciones. Realmente tiene que ser lo primero en ese archivo. Si pongo useClient aquí abajo, mi editor realmente va y lo cambia en una cadena diferente. Si lo hago aquí arriba y me deshago de eso, simplemente lo deja así. Y todo está bien.

9. Manejo de URLs y Mejora del Rendimiento

Short description:

Me encontré con un error con la URL al buscar datos en el servidor. Para solucionarlo, tuve que usar la URL completamente calificada en el contexto de localhost puerto 3000. Se hizo el mismo ajuste para la página de detalles. También expliqué que empujar los componentes al servidor mejora el rendimiento y permite una mejor compartición de código entre los navegadores. Mencioné los beneficios de usar async/await en lugar de useEffect para la búsqueda de datos. Por último, respondí a una pregunta sobre cómo manejar diferentes nombres de host al desplegar la aplicación utilizando variables de entorno.

Así que ahora obtengo un error diferente. Error runtime no manejado, falló al analizar la URL desde slash API slash películas. ¿De qué se trata todo esto? Bueno, si volvemos a esa página, podemos ver que aquí estamos haciendo una búsqueda de esa URL, y eso es a lo que realmente apunta. ¿Podemos ver eso realmente? No, realmente no podemos ver eso aquí. Pero confíen en mí, esto es a lo que apunta porque es realmente esta consulta la que estamos haciendo. No se está pasando ningún género aquí, así que estamos obteniendo todas las películas. ¿Por qué se está quejando aquí? Esto funcionaba perfectamente bien antes, antes de que esto ocurriera en el navegador, lo que significa que cualquier URL que uses, que sea una URL relativa como esta, básicamente se añade al dominio actual, al origen actual. Así que se ejecuta contra localhost puerto 3000. Ahora este componente se renderiza en el servidor, no en el cliente, lo que significa que ya no hay una URL relativa. Así que tengo que tomar esa URL y decir, bueno, queremos esta URL en el contexto de localhost puerto 3000. Y si guardo esto, debería funcionar de nuevo, y debería poder ir a un género diferente y todo eso sigue funcionando. Así que podemos hacer exactamente lo mismo con la página de detalles. Permítanme hacer eso rápidamente porque eso también contiene un useClient y la configuración es muy similar. UseState, efectos secundarios, etc. Así que esto devuelve una película así, y esto debería ser un componente asíncrono. Ahora podrías haber notado que en la página anterior, estaba usando una exportación por defecto tradicional función de página de películas. Aquí, estoy usando una función Lambda con SFC tipado como const, y todavía estoy haciendo la exportación por defecto debajo de aquí. Los React Server Components realmente no les importa. A Next no le importa. Esto simplemente funcionará. Tendré que hacer esto un poco más complejo, tendré que hacer de esto una URL completamente calificada, y ahora esto también debería funcionar. Vamos a comprobar doblemente que lo hace. Y no lo hace, porque de nuevo, estamos entrando en un contexto de creación. ¿Estamos usando uno por aquí? No, pero si entro en este formulario de película, por aquí, estamos usando UseToast y en realidad usa un contexto bajo el capó. Pero también hay mucha interactividad del lado del cliente, un formulario de entrada completo, etc. Así que esto necesita ser un componente del cliente. Así que básicamente lo que estoy haciendo es empujar esas directivas useClient más hacia las hojas del componente, y ahora se renderiza. Ahora, si miro la tarjeta de la película, simplemente hago que toda esta tarjeta sea un componente del cliente. Si lo miro, como todo esto de aquí arriba no es interactivo. La única interactividad son estos dos elementos aquí. Los detalles son en realidad un enlace, una etiqueta de anclaje. Así que ese comportamiento estándar del navegador no necesita ser renderizado en el cliente. Lo único es este botón. Así que tiene un manejador de clics. Así que eso es lo que realmente debería ser un componente del cliente. Así que en una aplicación real, en realidad iría y convertiría esto en un componente separado. Es el único que realmente usa ese gancho useShoppingCard. Así que eso es lo que haría un componente del lado del cliente y esta tarjeta también sería un componente del lado del servidor. Pero en interés del tiempo, en realidad no voy a hacer eso ahora mismo. Así que esto es básicamente lo que acabo de hacer. La principal razón para empujar las cosas al servidor es un mejor performance. Tu servidor es típicamente más rápido. Sólo se ejecuta una vez. La salida puede ser compartida entre diferentes navegadores. El código no tiene que ser enviado al navegador, etc. El código no tiene que ser enviado al navegador, etc. Lo que dije, puedo simplemente usar async await, que es mucho más agradable que tener que usar un efecto secundario como render de useEffect llamado update state, render de nuevo, etc. Previene una segunda búsqueda utilizando el segundo parámetro del useEffect. ¿Qué cambió, etc.? Mucho más agradable. Así que esta es la primera página que cambié, la lista de películas con todas las tarjetas de películas. Recuerda que fetch tiene que ser una URL completamente calificada. Para que eso funcione, esa tarjeta de películas se convirtió en un componente del cliente. Y luego hice lo mismo con el formulario de detalles de la película, no con el formulario de edición, y el formulario de edición en sí se convirtió en un useClient. Componentes para que se rendericen en el cliente porque realmente necesita ser interactivo. Así que veo una pregunta. Bueno, adelante. Hola, gracias. ¿Puedes volver una diapositiva atrás cuando en realidad. ¿Esta? Sí, sé o entiendo por qué necesitas poner la URL completamente calificada porque ya no estamos en el navegador. Sin embargo, puedo imaginar que la aplicación puede funcionar, se ejecuta en localhost cuando estás desarrollando localmente, pero cuando realmente despliegas en otro lugar, obtendrá un dominio diferente, un nombre de host diferente. ¿Hay algún truco o consejo o constante que uses para no repetir este nombre de host una y otra vez en todos tus componentes? Sí, esa es una excelente pregunta. Y debería haber mencionado eso. Lo que normalmente hago es crear una variable de entorno, y luego cuando despliego la aplicación, tengo una variable de entorno con el origen de la aplicación. Y simplemente apunto eso bien, convertido en desarrollo a localhost puerto 3000. Y luego cuando se despliega, por ejemplo, al solucionador de problemas puntos NL. Así que en runtime, cambia entre esos diferentes orígenes. Vale, lo tengo, gracias. ¿Alguna otra pregunta? Y en realidad puedo ver que hay un mensaje en el chat. Sí, había una nota en el chat de Valerio, Next soporta variables de entorno en su configuración.

QnA

Componentes del Servidor React y Next.js

Short description:

Los Componentes del Servidor React proporcionan una mejor seguridad de tipo al consultar directamente la base de datos en los componentes, utilizando Prisma para devoluciones de tipo específicas. Esto evita errores y acorta el ciclo de retroalimentación. Para múltiples interfaces de usuario, el acceso a los datos se puede colocar en una biblioteca compartida. Un componente del cliente puede tener un componente del servidor como hijo, permitiendo la composición. Solo un componente del servidor puede renderizar otro componente del servidor. Next.js es un servidor React capaz que está listo para aplicaciones de producción.

Y de hecho, muchas de mis aplicaciones, las aplicaciones de React están construidas con Next. Y normalmente las alojo en Foresell donde utilizo esas variables de entorno, realmente conveniente. ¿No hay más preguntas?

En ese caso, vamos a traer de vuelta a Jean-Luc Picard. Oh, hay otra pregunta de Luca. Adelante, Luca. Hola, sí, gracias por tu sesión. Mi pregunta es un poco más sobre el lado de la motivación. En la diapositiva 20, introdujiste que como llevar el código de vuelta al servidor o como integrar el código de back y front end conduciría a una mejor seguridad de tipo. ¿Ves alguna ventaja? Porque quiero decir, también podrías compartir los tipos con una biblioteca o algo así. Como, sí. ¿Hay alguna ventaja o simplemente?

Bueno, para empezar, déjame ir a la página de películas. Como aquí, estoy diciendo, por aquí, estoy diciendo, oh, espera, el JSON para esa respuesta. Si miro la tipificación, la función JSON de una solicitud devuelve una promesa de cualquier y no está tipada. Ahora, podría compartir estos tipos de película pero no hay garantía de que eso sea correcto. Solo estoy diciendo, está bien, consigue algunos datos y los voy a tratar como ese tipo. Pero si ese tipo es correcto, tal vez esté desactualizado pero tal vez sea el tipo completamente incorrecto. No hay ninguna comprobación allí. Así que es fácil cometer un error. Bastante a menudo cuando uso un REST como este, usaré algo como Swagger para generar mis tipos para mí pero entonces todavía podrían estar desincronizados con el servidor porque hay un paso de generación en medio. Lo mismo si usas GraphQL o algo así. Y uno de los próximos pasos aquí, en realidad vamos a cambiar esto de usar Fetch aquí pero simplemente vamos a hacer la consulta de la base de datos directamente en los componentes. Y luego tengo Prisma, que me devuelve un tipo específico exactamente los campos que solicité, etc. Tengo una seguridad de tipo mucho mejor. Sí. Sí, veo ese punto. Supongo que la seguridad de tipo sería equivalente si usas el Swagger para la generación de tipos pero simplemente te deshaces de ese paso intermedio, ¿verdad? Sí. Más eficiente. Es un paso adicional sin entrar en demasiados detalles. Pero en muchos casos trabajo en la aplicación del cliente y hay un equipo diferente trabajando en la aplicación del backend, a la que consultamos. Así que podrían haber desplegado una nueva versión de una API que en realidad no es compatible. Pero no obtengo errores de compilación. No veo eso hasta que actualizo los tipos o recibo algún error de tiempo de ejecución extraño diciendo que alguna propiedad que espero que esté, de repente está indefinida. Sí, lo veo. Y hacer eso más directamente previene, bueno, no previene estos errores pero los hace menos probables y hace que el ciclo de retroalimentación sea más corto. Mm-hmm. Si puedo añadir otra cosa, si tienes múltiples interfaces de usuario trabajando con la misma API que proporciona algunos modelos de datos que están canalizados, tendrías que replicar o distribuirías estos componentes del servidor entonces a todas estas interfaces de usuario? ¿Como si fueran operados por diferentes equipos?

Bueno, podría hacer eso. Depende un poco de los componentes del servidor. Más probablemente pondría el acceso a los datos. Como tengo, ¿dónde está? Tengo un archivo de servidor aquí en la, oh, lo siento, en lib. Tengo un archivo DB que usa el cliente Prisma. Como esto está básicamente ligado a un esquema específico que está definido. Pondría eso en una biblioteca compartida y lo usaría. Sí, lo veo. Genial. Que podría estar desincronizado pero ayuda. Arian tiene una pregunta. Sí, gracias, Maurice. Esto es realmente genial hasta ahora. Gracias. Tal vez podrías, solo quiero asegurarme de que entendí la parte con el límite del cliente y creo que una pregunta similar también fue planteada en el chat. Si tienes un componente del cliente y hay algo marcado con use client, ¿pueden los hijos ser componentes del servidor? Según lo entendí, sí, porque entonces parte de él es HTML que viene del servidor como parte de un componente del cliente o ¿estoy equivocado? Sería realmente interesante cómo esto se despliega hacia abajo. Sí, es en realidad algo a lo que voy a volver más tarde pero en resumen, sí, un componente del cliente puede tener un componente del servidor como hijo pero lo que el componente del cliente no puede hacer es renderizar un componente del servidor. Pero lo que puedes hacer es igual que tienes que prop de hijos en los componentes de React, un componente del servidor puede renderizar otro componente del servidor y pasarlo como hijo a los componentes del cliente y el componente del cliente entonces puede componer eso junto de la manera que quiera. Y de hecho, tengo una demostración de eso. Los hijos, sí, la parte de renderización, no. Solo un componente del servidor puede renderizar otros componentes del servidor pero puede pasarlo a un componente del cliente para la composición. Vamos a hacer esta parte. Hagamos que las primeras de estas dos páginas sean componentes del servidor y sus hijos componentes del cliente. Ahora mencioné que estaba usando Next y mencioné al principio que la parte del enrutador de la aplicación era importante. ¿Por qué? Y por esa materia, mencioné que React ahora requiere un servidor, que no siempre es el caso. Como solo es el caso donde estás usando los componentes del servidor React. Así que si no estás haciendo componentes del servidor React todavía puedes hacer React de la manera tradicional con solo cumplir solo componentes del cliente. Eso no ha desaparecido. Así que no te preocupes. Las aplicaciones existentes funcionarán tal como están. Pero si quieres entrar en los componentes del servidor React y empezar a usar esa capacidad entonces sí necesitas una parte del servidor. Necesita ser un servidor capaz de React. Lo que significa que necesitamos funcionalidad allí. Ahora hay varias opciones. Next es en mi opinión, la única que está lista para aplicaciones de producción.

Otras Opciones y Next.js

Short description:

Existen otras opciones como Waku y la demo de los Componentes del Servidor React, pero aún están en fase experimental y no se mantienen activamente. Next.js es la mejor opción para una aplicación en producción, especialmente con la participación del equipo de React.

Hay otras opciones como Waku, que es de Daishikato, que es una especie de marco mínimo de React, que es bastante interesante. Puedo recomendar echarle un vistazo, especialmente si quieres entender lo que está pasando bajo el capó. Es realmente agradable, pero todavía está muy en construcción y de ninguna manera está completo. Hace un tiempo, quería hacer una demo con Waku y de repente publicaron una nueva versión que ya no funcionaba en Windows. Así que todavía es muy experimental, aunque probablemente será bastante interesante. También está la demo de los Componentes del Servidor React del equipo de React, pero como dice el nombre es solo una demo, no se va a actualizar. Así que Next es realmente genial. Si construyes de la manera tradicional usando, digamos, create React app o feed, eso sigue siendo perfectamente válido, pero no tienes las partes del servidor allí. Algo que hubiera esperado de alguna manera era Remix, pero para Remix 2, que se lanzó relativamente recientemente, aún no hay soporte para los Componentes del Servidor React. Han anunciado que lo incluirán con Remix 3. Así que no tengo ni idea de cuándo será eso, pero definitivamente lo harán. Y tengo entendido que Shopify Hydrogen y Remix, por cierto, también es de Shopify estos días, pero se supone que Shopify Hydrogen es compatible con los Componentes del Servidor React. Ahora, nunca he usado Hydrogen, así que no puedo decir qué tan bien funciona y si eso es realmente cierto, es solo mi entendimiento. En lo que a mí respecta, Next es, con mucho, la mejor opción para hacer una aplicación en producción. Si solo porque bastantes personas del equipo de React se unieron a for sell y están trabajando en Next estos días.

Componentes del Servidor React y Renderizado

Short description:

Los componentes del servidor React se renderizan en el servidor y envían los resultados al cliente como una representación del DOM virtual. La fase de renderizado convierte los componentes en un DOM virtual, y React lo compara con el DOM real en el navegador. Los componentes del servidor React pueden ser asíncronos y utilizar una API de transmisión para enviar datos al cliente. El empaquetado de código en los componentes del servidor React permite paquetes más pequeños al excluir los componentes exclusivos del servidor. Next.js es un servidor adecuado para los componentes del servidor React debido a su funcionalidad y capacidades de empaquetado. Los cambios realizados en la aplicación pueden romperla, y la actualización de la caché puede causar problemas.

Ahora, ¿por qué necesitamos un servidor? ¿Y qué hace realmente? Porque es un componente del servidor React, se renderiza en el servidor. Pero con el renderizado del lado del servidor también estábamos renderizando componentes en el servidor. La diferencia, sin embargo, con los componentes del servidor React es que estamos renderizando en el servidor y estamos enviando los resultados al cliente. Y el resultado de llamar a una función de renderizado no es HTML, es básicamente una representación del DOM virtual. Así que obtendrás un objeto de vuelta que es una propiedad de tipo que podría ser diff o podría apuntar a otro componente React. Tiene un objeto con todas las props que se pasan a ese componente y tiene todos los hijos allí que también son props pero se tratan de manera un poco diferente. Así que básicamente es un objeto JavaScript o más probablemente una serie de objetos. Y esos pueden ser serializados como JSON y enviados al navegador y utilizados allí.

Con el renderizado del lado del servidor es la forma tradicional de usar React en el servidor. Es muy parecido al renderizado del lado del servidor que convierte todo en una gran corriente de HTML que envía este HTML al navegador. El navegador puede renderizar eso directamente lo que no sucede con los componentes del servidor React. Pero con el renderizado del lado del servidor los componentes completos de React también se envían al navegador y se vuelven a renderizar allí. Ahora con los componentes del servidor React tienes que tener en cuenta que React funciona en dos pasos. Primero hay una fase de renderizado donde conviertes un componente o una serie de componentes en un DOM virtual. Y el DOM virtual es esa estructura de objeto que mencioné con el tipo y las props, etc. Y luego está React en sí que compara ese DOM virtual con el DOM real, ve cuál es la diferencia y aplica esos cambios al DOM real. Con los componentes del servidor React eso todavía sucede en el navegador. Así que si haces puros componentes del servidor React sin renderizado del lado del servidor que no es lo que hace Next pero supongamos por un momento que estás haciendo eso no obtendrás ninguna interfaz de usuario en el navegador si JavaScript está desactivado. Realmente todavía necesitas React en el navegador incluso si todos tus componentes son componentes del servidor. Enviarás objetos adyacentes al navegador y en el navegador eso todavía será comparado contra el DOM y luego aplicado. Así que eso todavía sucede. Todavía necesitas React en el cliente. No es que React vaya a desaparecer. En casi todos los casos también tendrás componentes del cliente porque hay muy pocas aplicaciones de React que no son interactivas. Así que tendrás componentes adicionales siendo renderizados en el cliente. Pero incluso si no tienes ninguno, todavía es lógica del lado del cliente. Ahora, ese paso siempre estuvo allí. No es nada nuevo pero tradicionalmente todo eso simplemente sucedía en el cliente donde los componentes renderizados producirían ese DOM virtual y ese DOM virtual luego se aplicaría al DOM del navegador. Es solo que ese segundo paso era algo invisible pero siempre estuvo allí. Ahora están un poco más separados por lo que es un poco más evidente. Ahora los componentes del servidor React pueden ser asíncronos y eso tiene algunas implicaciones para el servidor porque significa que tu aplicación React puede renderizarse en el servidor y algunos componentes se harán inmediatamente porque no necesitan esperar nada pero otros tendrán que esperar cosas y eso podría llevar potencialmente mucho tiempo, quizás segundos, quizás incluso más que segundos. Así que para acomodar eso y renderizar las cosas en el navegador lo más rápido posible, un servidor React en realidad usará una API de transmisión para enviar todo eso al cliente. Tendré una captura de pantalla más tarde sobre cómo se ve realmente la carga útil pero puedes ver eso en el navegador. Si voy aquí y abro la pestaña de red y refresco esto, deberíamos poder verlo aquí. ¿Por qué no lo estoy viendo todavía? Déjame intentarlo de nuevo. Verás solicitudes como esta que tienen un signo de interrogación, guión bajo, error C es y luego algún tipo de identificador después de eso. Estas son solicitudes donde el servidor React realmente transmite cosas asíncronas de vuelta al cliente o no necesariamente necesita ser asíncrono. Si miras en la respuesta, puedes ver, bueno, en este caso, había una línea. Aquí puedes ver que en realidad se renderizó más data. Así que ves que estamos en modo de desarrollo. Ahora básicamente cada línea aquí se transmite por separado. Parece un poco a JSON. No lo es realmente porque cada línea es una cosa separada. Y puedes ver varias líneas siendo transmitidas como un bloque y luego un poco más tarde, unas pocas líneas más, etc. Esa es la forma en que las cosas van al navegador. Típicamente, no necesitas preocuparte por cómo sucede eso pero es solo para que estés al tanto.

Otra razón por la que necesitas un servidor React específico con capacidades adicionales y un proceso de construcción especial es el empaquetado de código. Si un componente del servidor no se utiliza en el cliente, entonces no hay razón para enviar ese código o cualquiera de sus dependencias al navegador. Y esas dependencias podrían ser grandes modules de NPM, lo que significa que tu paquete se vuelve mucho más pequeño. Pero eso también significa que tienes una base de código. Y si vuelvo a mi aplicación, aquí, estoy importando una tarjeta de película que se ejecuta en el cliente pero esto no se ejecuta en el cliente. Así que no es cuestión de que web pack entre diciendo, vale, tenemos estos componentes, necesitamos empaquetar esto. Necesitamos empaquetar todas las dependencias. Tiene que averiguar, vale, tenemos cosas que necesitamos para el servidor, tenemos cosas que necesitamos para el cliente. Y en este punto, todavía lo estamos haciendo a nivel de archivo pero cuando lleguemos a los accesos al servidor, en realidad comenzaremos a incrustar funciones dentro de los componentes donde parte de ello se ejecuta en el cliente y parte de ello se ejecuta en el servidor, lo que lo hace aún más interesante. Así que todo el proceso de empaquetado allí es bastante más complicado en servir el código correcto y todo eso. Por eso necesitas algo como Next o Voxel o en el futuro, un servidor como Remix capaz de hacer eso que tiene mucha funcionalidad. Y no puedes simplemente usar algo como Create React App o Feet, por esa materia, no deberías usar Create React App más porque ha sido deprecado. Pero incluso Feet es solo la forma tradicional donde todo sucede en el cliente y terminas con solo un paquete siendo enviado al navegador. Por eso usamos Next.

Ahora, un poco sobre cómo se actualizan las cosas en la caché porque cambiamos nuestra aplicación pero sin darnos cuenta, en realidad rompimos nuestra aplicación. Y déjame mostrarte algo. Tenemos El Padrino aquí solo por si acaso. El Padrino aquí, igual que antes. Puedo ir a los detalles. Puedo hacer un cambio aquí. Lo llamaré El Padrino uno porque esa era la primera parte. Puedo pulsar enviar. Vemos el mensaje de película actualizada igual que antes. Vuelvo a la lista y no hay un uno aquí.

Solución de problemas de actualizaciones de la interfaz de usuario y caché

Short description:

La interfaz de usuario no se actualiza inmediatamente después de que se actualiza la base de datos. Esto se debe al mecanismo de caché de Next, que tiene cuatro capas de caché diferentes. El problema radica en la caché de ruta completa en el servidor y la caché de ruta en el cliente. Para solucionar esto, podemos invalidar la caché exportando una constante 'dynamic' establecida en 'force dynamic'. Después de actualizar la página, las actualizaciones ahora se reflejan correctamente.

Todavía es el Padrino. Puedo tomar esto, abrirlo en un nuevo navegador. Todavía no hay nadie allí. Así que no es algo en la caché del navegador local. Podría abrir esta página en Firefox, un navegador diferente. Todavía no diría el Padrino uno. ¿Falló la actualización o algo así? Bueno, echemos un vistazo en la database. Tengo Prisma aquí, Prisma Studio, que nos permitirá consultar la database directamente. Y abramos las películas. ¿Dónde está el Padrino aquí? Dice Padrino uno. Así que la database fue actualizada, pero por alguna razón la interfaz de usuario no lo está. Como puedo hacer clic y todavía no se actualiza. Ahora, si hago una actualización forzada, estoy haciendo control F5, Ahora se actualiza y se convierte en el Padrino uno. Así que parece que eventualmente recogerá las cosas, pero no inmediatamente. Este eventualmente es solo porque estoy usando la versión de desarrollo de Next. Si construyo esta aplicación en una versión de producción y estaba ejecutando Next en producción, entonces esto no habría sucedido y todavía habría visto al Padrino. Nunca lo habría recogido. Entonces, ¿qué está pasando aquí? Next hace mucho caché y tengo un enlace aquí a la documentation de Next. Y si vas a la caché aquí, puedes ver cómo va. Dice, aquí mismo. Puedes ver que hay cuatro capas de caché diferentes involucradas. Hay memorización de solicitudes, lo que significa que en un ciclo de renderizado dado, si solicitas los mismos data usando fetch varias veces, solo va a hacer ese fetch una vez y servirá el resultado varias veces, lo cual es bastante bueno. Puedes ver aquí, es por solicitud. Hay una caché de data. Que es utilizada por la caché de memorización entre otras cosas. Hay una caché de ruta completa, que es con la que tenemos problemas en este momento. Y hay una caché de enrutador, pero esta es una caché del cliente. Las tres primeras son cachés del servidor. La última es una caché del cliente. Resulta que en este momento tenemos un problema con esa caché de ruta completa en el servidor y con una caché de ruta en el cliente. Así que resolvamos esos problemas. Vamos primero a esa caché de ruta completa. Y en algún lugar por aquí, déjame, esta caché de ruta completa aquí. Hay una opción sobre cómo podemos invalidar esta caché. Y hay un par de formas diferentes, pero por ahora lo que podemos hacer es usar cualquiera de estas dos. Dile a Next que esta es una página dinámica porque ahora piensa que no lo es. Y la mejor manera de hacer eso es exportando una constante dinámica, que se establece en la cadena force dynamic. Vamos a agregar esa exportación aquí. Y necesitamos hacer exactamente lo mismo en esta página. Esta página, esa es la página de edición de películas. Y veamos si las cosas están mejor ahora. Así que acabo de presionar F5 para actualizar para asegurarme de que no tenemos nada todavía en nuestra caché. Tenemos Padrino 1. Voy a Detalles. Cambio esto a 2. Enviar, ves el mensaje de película actualizada de nuevo. Voy a Películas y todavía dice 1. No parece muy bueno. Así que abramos esto en una nueva pestaña. En esta pestaña, en realidad dice Padrino 2. Recuerda que antes, cuando abrí un navegador diferente, todavía solo veíamos al Padrino. No recogió el cambio. Ahora ha recogido el cambio en una pestaña diferente o en un navegador diferente. Aquí todavía vemos 1. Veamos si todavía dice...

Gestión de la Caché del Enrutador y Páginas Dinámicas

Short description:

Next.js tiene una caché de enrutador que funciona en el cliente para prevenir solicitudes innecesarias al servidor. No puede ser desactivada, pero existe una API para controlarla. Al usar el método de actualización del enrutador de Next, puedes invalidar la caché del enrutador del lado del cliente. Esto asegura que los datos actualizados se reflejen inmediatamente en la aplicación. La duración de la caché para las páginas renderizadas dinámicamente es de 30 segundos, mientras que las páginas renderizadas estáticamente se almacenan en caché durante cinco minutos. La variable force dynamic se añade a las páginas de película y detalles de película para indicar que deben ser consideradas páginas dinámicas. Esto permite que Next.js las vuelva a renderizar cuando la base de datos ha cambiado.

Bien, ahora también ha recogido el 2. Así que Next o React, como quieras verlo. Next, en este caso para ser exactos, está recogiendo los cambios pero solo después de un tiempo. Así que la segunda parte del problema que mencioné fue esta caché de enrutador. Esta caché de enrutador funciona en el cliente y almacena páginas en el cliente para prevenir la pérdida de solicitudes al servidor. Sin esta caché de enrutador, cada vez que navegas en el cliente, habría una solicitud yendo al servidor. ¿Esta página todavía está actualizada? Y si no, dame una versión más nueva. Esta caché de enrutador previene todas esas solicitudes.

El problema, sin embargo, con esta solicitud de enrutador, si la caché completa del enrutador, optar por salir aquí, optar por salir, dice que no es posible optar por salir. No puedes desactivar esto, no puedes decirle que no haga nada. Hay algo sobre aquí cuando estás usando el cliente para optar por salir, sobre aquí cuando estás usando un enlace, puedes establecer prefetch en falso, pero eso no opta por salir de la caché del enrutador. Solo significa que no se hace prefetch, que ya se usa para poblar la caché del enrutador en advanced. Todavía se usa, pero hay una API que podemos usar para controlar esto.

Así que si vuelvo al formulario de película, el formulario del lado del cliente, justo aquí, después de que hemos enviado la película al servidor y eso está hecho, podemos decirle a Next que la caché del enrutador del lado del cliente debe ser invalidada. Así que vamos a importar UseRouter. Y cada vez que importas UseRouter, ves que hay dos versiones. Hay un enrutador Next, déjame ampliar esto un poco. Así que aquí ves que hay Next / enrutador y hay Next / navegación. Eso es un poco confuso. La regla es Next / enrutador es el enrutador tradicional, que está destinado para la biblioteca de Páginas. Next / navegación es el nuevo enrutador, que está destinado para el directorio de aplicaciones. Así que si estás usando el enrutador de aplicaciones, usa Next / navegación. Un nombre ligeramente diferente habría ayudado aquí, pero tienes que recordar que Next / enrutador significa Páginas, Next / navegación significa App. Y puedes usar ambos juntos si quieres. Así que vamos a importar ese. Haremos referencia al enrutador y aquí, diré enrutador. Y puedo navegar con él, pero eso no es lo que queremos hacer. Solo quiero llamar a refresh. Así que refresh básicamente significa ve a refrescar tus cachés. Podrían estar obsoletas, límpialas y carga data de nuevo según sea necesario. Y con eso, si vuelvo a tu aplicación y hago otro cambio, en realidad volvamos atrás y refresquemos para asegurarnos de que no tenemos ninguna caché obsoleta. Así que toma El Padrino 2, lo cambiaré a El Padrino 3, enviaré. Y podrías haber notado que hubo un breve parpadeo porque esta página en realidad se recargó como parte de ese router.refresh. Y no lo señalé antes, pero antes el título aquí, no cambió. Ahora se actualizó inmediatamente a El Padrino 3. Y si vuelvo a la lista de películas, esto también se actualizó inmediatamente. Así que esto es específico de Next, estas cachés son específicas de Next, pero dado que la mayoría de las personas que usarán React Server Components, al menos en el futuro previsible, usarán Next.js se encontrarán con esto. Y realmente tienes que asegurarte de entender todas las implicaciones aquí de la caché y cómo funcionan las cosas. Y resulta que más tarde, entraremos en React Server actions, esas harán esto aún más complejo. Pero, o más complejo, bueno diferente es una mejor manera de describirlo. En muchos casos, en realidad va a ser más simple. Así que el primer cambio que hice estableciendo el código a las páginas que estoy usando para usar force dynamic para asegurarme de que se renderizan dinámicamente. Eso todavía tiene que hacerse incluso si haces ese refresco del navegador, lo siento ese refresco del enrutador. Y estoy llamando a router refresh después de que hemos actualizado la película. En caso de que te estés preguntando qué sucede en un escenario de varios usuarios, el usuario que hizo las actualizaciones ejecutará el refresco del navegador. Así que su enrutador local será refrescado y verá los cambios inmediatamente. El segundo usuario no lo hará. Si ya ha visitado esa página y la visita de nuevo, obtendrá los data de su caché de enrutador local y con la página dinámica esa caché de enrutador dura 30 segundos. Así que los primeros 30 segundos, todavía mirará data obsoletos. Si no es dinámico, una página estática, entonces la caché, creo que eran cinco minutos. Déjame comprobar. Está justo en algún lugar aquí. Sí, la página renderizada dinámicamente es de 30 segundos. Una página renderizada estáticamente se almacena en caché durante cinco minutos. Así que el otro usuario recibirá una notificación o recibirá las actualizaciones, pero solo después de un tiempo. Así que la otra exportación dinámica que añadí. Así que vamos a hacer eso. Asegúrate de que estas ediciones funcionen de nuevo en tu versión añadiendo el force dynamic y el enrutador. Y después de eso, en realidad echaremos un vistazo a la actualización de los componentes, deshaciéndonos del fetch y haciendo que toda esa consulta de la database sea mucho más directa, lo cual es bastante agradable. Pero haremos eso después de este paso. ¿Alguna pregunta antes de abrir la sala de breakout? Sí, Vanessa. ¿Puedes mostrarme una vez más qué es esa variable force dynamic y dónde se está utilizando? ¿Esta variable force dynamic? Sí. Así que añadí eso a las dos páginas, la página de película y la página de detalles de la película. Así que básicamente esto, las exportaciones, consts, el valor aquí force dynamic básicamente significa que esta página debe ser considerada por Next como una página dinámica, no como una página estática. Porque por defecto, Next concluye que esta es una página estática. No necesita volver a renderizarla cuando la solicitas de nuevo, porque piensa que solo va a terminar con el mismo resultado, lo cual obviamente no es el caso si la database ha cambiado. Vale. Y esa variable no se usa en ningún lugar, solo la declaramos allí y la exportamos. Sí. La exportas, tiene que tener este nombre, pero es una de esas exportaciones de marcador para Next, que tienes una página, porque esto tiene que estar en la página misma, no en algunos componentes, sino en la página real.

Consulta Directa a la Base de Datos y Mejoras de Tipo

Short description:

Hay un montón de cosas que puedes exportar allí, que ajustan el comportamiento de cómo funciona Next. Todavía estábamos haciendo una búsqueda desde nuestras dos páginas, pero en realidad podríamos hacer las cosas un poco más directas ahora y simplemente consultar la base de datos allí. Fetch devuelve una promesa de cualquier cosa, por lo que no está tipado. En realidad, podemos hacer cosas directamente en el servidor e ignorar toda esta parte de búsqueda aquí. Ahora en mi componente, estoy consultando directamente la base de datos. No más solicitudes de búsqueda, no más tipos, y las cosas van a ser más rápidas y mejor tipadas.

Hay un montón de cosas que puedes exportar allí, que ajustan el comportamiento de cómo funciona Next. Vale. Gracias. Es un poco mágico, me di cuenta de eso, especialmente si nunca has visto esto y qué tipo de valores hay, no están tipados ni nada. Es solo esta cadena mágica. Estoy exportando con el nombre mágico. Y es un poco difícil de trabajar con ello, pero estoy seguro de que han considerado seriamente si hay una forma más fácil. Y no creo que la haya.

Luego, déjame abrir de nuevo la sala de breakout. Hagamos este ejercicio. Vale. Mencioné antes, todavía estábamos haciendo una búsqueda desde nuestras dos páginas, que hicimos asíncronas, pero en realidad podríamos hacer las cosas un poco más directas ahora y simplemente consultar la database allí. Y eso va a ser útil. Hay menos código, pero también va a ser más rápido, porque ahora el navegador envía una solicitud al servidor. ¿Puedes renderizar una página para mí? Hay un componente de servidor React. Los React server components dicen, vale, puedo renderizar esto. Voy a hacer una búsqueda, volviendo al mismo servidor. Alguno otro código allí se ejecuta, obtiene el resultado de la database, serializa eso como JSON, lo envía por el cable de vuelta al mismo servidor, al mismo proceso incluso. Deserializa ese JSON en un objeto y comienza a trabajar con él. Eso es mucho tráfico de red y serialización, deserialización, de las que podemos deshacernos.

Lo otro que mencioné es, bueno, fetch devuelve una promesa de cualquier cosa. Así que no está tipado. Y yo, siendo un fanático de TypeScript, me gustan las cosas tipadas. Me gusta la retroalimentación rápida, si algo está mal y mis consultas y props, etc, no coinciden. Así que en realidad podemos hacer cosas directamente en el servidor e ignorar toda esta parte de búsqueda aquí. Porque si miramos esta búsqueda, que estamos haciendo aquí, vamos a localhost puerto 3000 y luego a API películas con un género específico o sin ese género. Y está esta API películas, esta una ruta, que se ejecuta. Así que básicamente obtiene el género de los parámetros de búsqueda y luego llama a este getMovie. Y este getMovie en realidad va a la database y hace lo que necesita hacer. Así que simplemente agarremos toda esta función. Muévela a la página compartida. Necesitamos resolver algunas cosas, resolver las importaciones faltantes. Así que Prisma y los tipos de Prisma fueron resueltos. Y ahora en lugar de hacer esto, estos dos, podemos simplemente llamar a getMovies, pasando el género solicitado. El género solicitado. Ahora hay un pequeño desajuste de tipo aquí porque dice que el género es cadena o indefinido y la función solicita una cadena o nulo porque ligera diferencia en cómo funcionan las cosas. Pero si arreglo eso ahora, ¿Arreglé el equivocado? No, arreglé el correcto. Solo desplacé mal. Y deshagámonos de esto. Eso debería estar casi bien. Necesito agregar un await allí porque devuelve una promesa, es asíncrono. Así que ahora en mi componente estoy consultando directamente la database. No más solicitudes de búsqueda, no más tipos y las cosas van a ser más rápidas y mejor tipadas porque veo exactamente lo que estoy obteniendo de vuelta de la database aquí. Así que supongamos que uso algo más, tengo un ID dos aquí, obtengo inmediatamente un error de compilación que dice que ID dos no coincide. Y puedo hacer exactamente lo mismo en la página de detalles. Tenemos la solicitud de búsqueda. Va a, ¿dónde está? Este manejador de ruta que usa este getMovie justo aquí arriba. Muévelo aquí. Y de nuevo, resolvemos la importación para Prisma. Nos deshacemos de esto. getMovie con el ID como parámetro. Así que más simple y más rápido. Asegurémonos de que realmente funciona. Así que esta página se renderiza bien. Voy a los detalles y no se renderiza bien. Así que algo se rompió aquí. Interesante, veamos qué rompí. Hice un getMovie y debería haber notado ya el error de compilación aquí. Título no existe en promesa de, olvidé esperar. Así que el error de compilación se ha ido. Y esto se vuelve a renderizar con data ahora. Así que si agarro otra película, vemos los data directamente. Y ahora también es relativamente fácil solucionar otro problema porque supongamos que obtengo algún ID de una película que no existe. Ahora me quedo con cargando película punto, punto, punto. Así que el componente piensa que todavía estamos cargando una película. Pero en realidad, solo estoy pidiendo películas inexistentes. Así que esto no es exactamente correcto. Y podría esperar para siempre. Esto nunca se va a resolver en una película, que básicamente dice, bueno, si esto no devuelve una película, eso es lo que estamos renderizando. Así que lo que podríamos hacer en su lugar es findFirst, podríamos hacer un findFirst o un throw.

Manejo de Datos de Películas y Uso de Suspense

Short description:

Cuando se encuentra una película, se resuelve. Si no se encuentra ninguna película, se lanza un error. El código para manejar los estados de carga puede ser eliminado, ya que el objeto de la película está disponible debajo de la llamada awaitGetMovie. Sin embargo, todavía puede haber una necesidad de una interfaz de usuario de carga. Los Componentes de Servidor de React ofrecen una mejor solución para manejar los estados de carga utilizando suspense.

Entonces, si encontramos una película, la resolvemos. Si no encontramos una película, en realidad lanzamos un error. Y ahora no tengo configurada una página de error, pero aparece un poco feo, pero ahora obtenemos ese error, no se encontró ninguna película. Y también significa que este código puede desaparecer porque si llegamos debajo de este awaitGetMovie, tenemos un objeto de película. No hay cuestión de un estado de carga allí. Por supuesto, podría ser lento. Esto todavía se llenará, por supuesto. Pero ahora para una película existente, funciona bien de nuevo. Volvamos a la Redención de Shawshank. Y eso carga bien. Ahora, como mencioné, las cosas pueden ser lentas. Así que todavía podríamos necesitar alguna interfaz de usuario de carga, como acabo de eliminar, pero con los Componentes de Servidor de React, hay una forma mucho mejor de hacer eso. Y eso es usando suspense. Y volveré a eso en un minuto para mostrar realmente cómo funciona suspense.

Retroalimentación Inmediata y Optimización de Consultas de Base de Datos

Short description:

En mi proyecto, tengo un paso de compilación que proporciona retroalimentación inmediata sobre los errores. Esto me ayuda a detectar y corregir rápidamente los errores de compilación. También me permite eliminar puntos finales de API innecesarios y mejorar el código. Puedo consultar la base de datos directamente en el componente o abstraerlo en una capa de API. Al seleccionar campos específicos en la consulta, puedo optimizar la recuperación de datos. Aunque no haremos el ejercicio ahora, usar Satisfies y el tipo de tarjeta de película sería una buena manera de optimizar la consulta. Tomemos un descanso para tomar café antes de continuar.

Entonces, director más simple, obtengo una retroalimentación más inmediata de las cosas que están incorrectas. En realidad, aún no lo mostré, pero lo que normalmente tengo en mi proyecto es un paso de compilación como este, que ejecutaré con una opción de observación. Entonces, esto se mantiene ejecutando en segundo plano. Y si en algún lugar de mi código hay un error de compilación, como si eliminara ese peso nuevamente, inmediatamente veo aquí, está bien, algo está mal. Hay un error de compilación. Vamos a solucionarlo. E incluso sugiere aquí desde, bueno, parece que debería haber un peso. Lo vuelvo a agregar, guardo, y ya no hay errores. Por supuesto, esto funciona en este proyecto porque es relativamente pequeño. En un proyecto algo más grande, no lo tendría constantemente en ejecución porque se volvería lento. Pero regularmente llamaría a un script de compilación para hacer lo mismo, especialmente antes de comprometerme o subir cambios a una rama de solicitud de extracción o algo así. Entonces, un pequeño cambio, pero con muchos beneficios, hace que el código sea más rápido, más fácil. Realmente puedo deshacerme de esos puntos finales de API. Ya no los necesito. Los dejé por ahora. Pero en realidad, sería mejor eliminarlos. No se usan. Entonces aquí es donde eliminé las solicitudes get y el otro podría haber sido eliminado por completo. Así que por favor vayan y hagan el mismo cambio a menos que haya alguna pregunta que quieran hacer primero. Luego, permítanme mostrar rápidamente uno de los beneficios de hacer una consulta a la database de esta manera directamente en el componente. O lo que haría en una aplicación real es que no lo haría en el componente en sí. Lo abstractaría en una capa de API, pero serían funciones llamadas desde los componentes y no pasaría por una consulta RESTful. Pero una cosa que puedo hacer es si voy a esa página de películas, estoy consultando películas aquí. Tomemos este ejemplo. Solo estoy diciendo que encuentre todas las películas, ordénelas por un orden específico, que es por el voto promedio descendente. Y luego estoy devolviendo eso y pasando esas películas aquí a la tarjeta de película. Pero si miro la tarjeta de película, esa propiedad de película, ¿qué es lo que realmente quiere? Bueno, no quiere una película completa. Solo necesita un puñado de propiedades allí. Si miro toda la película, hay una fecha de lanzamiento allí, pero no se usa. Hay una ruta de puerta trasera y una ruta de póster, dos imágenes diferentes. Bueno, solo estamos usando la ruta de la puerta trasera, no la ruta del póster. Hay una popularidad allí que no estamos usando. Ahora, en este caso, el número de películas no es enorme. El número de elementos de data que estoy consultando y no usando no es enorme, por lo que no es terrible. Pero básicamente estoy consultando demasiado. Entonces, una cosa que puedo hacer ahora es que puedo entrar aquí y puedes agregar una cláusula de selección allí diciendo, solo quiero campos específicos. Y aparece con un montón. Pero quiero hacer esto un poco diferente porque tengo dos consultas diferentes en marcha. Así que seleccionemos por aquí. E incluya las mismas selecciones cuando estemos consultando por género. Ahora, AutoComplete agregó un montón de campos allí, pero ahora inmediatamente obtengo un error de compilación aquí diciendo, bueno, me faltan varios de ellos. Ahora, obtengamos los correctos. Esos son los que quiero. Deshazte de esta lista por un momento, y convierte estos en... ¿Por qué eso no está funcionando? ¿Y un poco mejor? Así que ahora debería seleccionar solo los campos correctos. Y si digo, si olvido uno, obtendré un error de compilación inmediato aquí abajo diciendo que las películas que selecciono no coinciden con las películas que quiero. Y al escribir esto un poco mejor, puedo hacerlo de manera que si quiero, que si selecciono un campo de más, obtendría un error de compilación también. En realidad no voy a hacer eso. En realidad no vamos a hacer este ejercicio por falta de tiempo, pero es una buena optimization porque tengo una consulta ahora de la database para este caso de uso específico. Porque también el caso de uso general es que así que en general, en los servidores REST, ordenar las cosas por voto promedio probablemente no sería el mejor orden de clasificación predeterminado para algún tipo de servicio REST. Ordenar por ID o título habría sido más apropiado. Entonces, usar Satisfies en realidad es una buena manera de escribir esto, y usar el tipo de la tarjeta de película en realidad haría esto aún mejor para que podamos especificarlo muy exacto. Pero como dije, vamos a saltar este ejercicio por falta de tiempo. De lo contrario, nunca llegaremos a esta parte. Tiempo para un descanso para tomar café.

Uso de Suspense con Componentes de Servidor de React

Short description:

Next.js proporciona una página loading.tsx que se renderiza mientras la página aún se está cargando. Esto es conveniente y permite una interfaz de usuario personalizada. Al crear un componente loading.tsx junto con el page.tsx, podemos mostrar un spinner mientras la página se está cargando. El spinner desaparece una vez que las películas se han cargado. Next.js mira la carpeta actual y sus padres para determinar si una página de carga está presente. La página loading.tsx es una API específica de Next y no forma parte de los componentes de servidor de React estándar. Next.js es adecuado para aplicaciones de pila completa a nivel empresarial, pero la parte de backend de Next no siempre es necesaria.

Entonces, la siguiente parte que quiero examinar es el uso de Suspense con los React Server components. Pero la primera parte que voy a ver específicamente son las páginas. Así que esto es algo específico de Next. Después de eso, voy a ver cómo podemos hacerlo de una manera más general con los componentes Suspense. Pero en ambos casos, en realidad va a usar Suspense. Siempre puedes envolver los React Server components alrededor de un límite de suspense y poner una interfaz de usuario de respaldo allí. Mientras todavía están suspendidos, no completados aún, mostrarán esa interfaz de usuario de respaldo. Es realmente genial y lo usaremos en un minuto.

Pero para las páginas, Next.js agrega una API específica de Next y eso es que puedes tener un loading.tsx. Así que una página de carga allí, que se renderiza mientras esa página todavía se está cargando. Lo cual es bastante conveniente y hace que sea bastante fácil tener una interfaz de usuario personalizada allí. Así que echemos un vistazo rápido a cuándo sería necesario. Así que hagamos que esta página se cargue lentamente, o al menos hagamos que la función GetMovies se ejecute lentamente. Y tengo una pequeña función de ayuda, sleep. Y puedo pasar un tiempo de espera, 200 milisegundos y lo esperaremos. Lo que hace que obtener la lista de películas sea bastante pequeña, o bastante lenta. Vamos aquí, asegurémonos de que nada esté en la caché local actualizando y haré clic en películas. Y ahora vemos que prácticamente no pasó nada. Como, si voy de nuevo, es rápido. Como, vemos la lista de películas aparecer prácticamente de inmediato. Pero si estoy en la página de inicio, actualizo de nuevo para borrar las cachés. Hago clic en películas, así que acabo de hacer clic. Tarda un poco y no hubo retroalimentación.

Ahora, ¿cómo se renderizan las cosas? Hay este archivo de diseño y aquí, hay estos hijos y este es básicamente el hijo que queremos mostrar. Aquí es básicamente donde se renderizan las páginas. Ahora podrías poner un límite de suspense alrededor de esto, pero eso en realidad no funciona muy bien. Así que esa no es la forma recomendada de hacerlo. La forma recomendada es junto a este page.tsx, que denota básicamente un punto final, algún tipo de página, crearemos un loading.tsx. Y aquí crearemos un pequeño componente, exporta por defecto. Simplemente lo haremos devolver loading y home no es realmente un buen nombre para esto. Aunque en runtime, a Next no le importa. A Next no le importa, es solo la exportación por defecto. Así que ahora si hago lo mismo, voy a la página de inicio, asegurándome de que no haya nada en la caché. Voy a películas, vemos loading allí, lo cual es conveniente. Y la próxima vez que vaya allí, ya estará en la caché. Así que no hay necesidad de hacer lo mismo de nuevo. De hecho, pongamos una interfaz de usuario un poco más agradable aquí. Volvamos a las diapositivas y déjame simplemente copiar este componente. Así que muestra un bonito spinner y es un poco más agradable, pero el resultado final es exactamente el mismo. Voy a casa, hago clic en películas, vemos un bonito spinner y una vez que las películas se han cargado aparecen. Si voy a detalles, brevemente vemos ese spinner. Es un componente asíncrono. No puse un sueño allí, pero todavía es asíncrono. Toma un breve momento para cargar realmente los datos de la película. Si voy a otro como detalles, brevemente vemos ese spinner de nuevo. La razón por la que lo ves aquí también es que Next básicamente mira la carpeta actual. Así que por aquí, mira si esta página se está recargando. Lo usa para esta página. Mira si estamos cargando en esta carpeta, no, en ese caso subirá y verá si está allí. Así que está, lo carga. Si hubiera uno localmente aquí, simplemente lo usaría. Lo cual es bastante conveniente. De hecho, deshagámonos del sueño, para que sea agradable y rápido de nuevo. No quería abrir eso de nuevo. Así que aquí, para dormir en la función de obtener películas. Y en este caso, también agregué para dormir en la página de detalles de la película para que también se cargue un poco más lento. Pero incluso sin eso, ya puedes ver brevemente que aparece ese spinner. Y de hecho, debería poder ver eso en, esta página también, como está allí, es notable. No tarda mucho, pero aparece incluso sin dormir. Así que por favor vayan y agreguen esto. Recuerden, esta es una API específica de Next. Esto no es estándar en los React server components. Pero los React server components son conscientes de Suspense. Y te lo mostraré en un segundo. Los React server components son conscientes de Suspense. Y te mostraré otro ejemplo donde en realidad vamos a usar suspense para mostrar una interfaz de usuario de respaldo. Tengo una pregunta, Miros. Sí, adelante. Obviamente, con Next.js, siendo una aplicación de pila completa, ¿qué crees que es como la viabilidad es como si tuvieras que hacer aplicaciones a nivel empresarial como una empresa más grande usándola para full-stack? Realmente depende un poco de tu empresa. Como mencioné, estoy usando Next.js mucho, pero en la mayoría de las aplicaciones de producción, en realidad no uso la parte de backend de Next tanto.

Uso de Componentes de Servidor de React con Next.js

Short description:

El equipo de backend prefiere usar la pila .NET y quiere lanzar de forma independiente del frontend. Next.js se utiliza principalmente para proyectos personales, mientras que la empresa utiliza Express para el backend. Los componentes de servidor de React utilizan streaming y se pueden utilizar con APIs específicas de Next para actualizar la UI. El diseño del sitio, incluyendo el selector de género, necesita funcionar tanto en el cliente como en el servidor. El carrito de compras y los parámetros de búsqueda del nombre de la ruta requieren funcionalidad del lado del cliente. El objetivo es convertir el diseño en un componente de servidor o dividirlo en un componente de cliente y servidor.

Hay dos razones para ello. En primer lugar, el equipo de backend con el que trabajo está compuesto principalmente por desarrolladores de C-sharp. Desarrolladores de C-sharp, por lo que están utilizando la pila .NET, y la mayoría de nuestro backend está en .NET o Python, no en Node, y realmente no quieren usar el mismo backend. Y también quieren poder lanzar de forma independiente del lanzamiento del frontend. Así que sólo estoy utilizando un conjunto relativamente pequeño de la funcionalidad de backend de Next.js. Sí, así que cuando estoy usando Next.js, es principalmente para proyectos personales, pero obviamente en nuestra empresa tenemos unos 20 desarrolladores. Así que estamos usando Express para nuestro backend en un repositorio separado. Y me estaba preguntando si hay casos de uso de personas que lo utilizan en una empresa más grande? Bueno, todavía uso Next.js entonces. Para el frontend, sí, sí, sí. Para el frontend, sí, pero también algo relacionado con el backend. Como para la authentication estoy usando NextAuth, así que eso utiliza el backend de Next, pero no en un sentido de aplicación más general. Así que nos conectamos usando NextAuth, enviamos un token OAuth al backend, y el backend utiliza su propia biblioteca, pero el proveedor real es Azure AD, así que ambos utilizamos el mismo backend. Vale, eso es interesante. Y utilizamos las cosas de optimization de imagen de Next y algunas más, pero la funcionalidad de negocio real no está en el backend de Next. Sí, creo que ese es el enfoque que estamos buscando tomar para nuestra empresa, migrar nuestro frontend para usar Next.js. Sí. Pero sólo el frontend. Vale, todo el mundo ha vuelto, así que continuemos. Ya mencioné y ya demostré que el componente de servidor de React utiliza streaming, así que en realidad tengo una captura de pantalla aquí de cómo se veía eso. La razón por la que tengo una captura de pantalla aquí es que normalmente si intento mirar la respuesta en Chrome, Chrome no mostrará realmente la respuesta de streaming. Ahora mismo, lo hizo, así que esto no es muy útil. Déjame retroceder un paso, porque había una cosa que pasé por alto un poco. Cuando llegas a las acciones de servidor de React, contendrá el mismo tipo de flujo de vuelta a los clientes. Y en ese caso, puedes usar un par de APIs específicas de Next, revalidate path y revalidate tag, para invalidar ciertas cantidades de data o rutas. Estos pueden ser transmitidos de vuelta en la respuesta de la acción del servidor y ser utilizados en el cliente para actualizar cosas. Así que podrías actualizar una película usando la acción del servidor. Y como parte de la actualización, la respuesta volvería a renderizar parte de la UI, lo cual es muy conveniente. Entonces, ¿qué otra cosa querría usar como un componente de servidor de React? El diseño del sitio. Si miro el diseño del sitio ahora, primero veamos, que es básicamente la barra de navegación superior. En realidad no hay mucho más en ello, pero normalmente tendrías pies de página allí, algo así como este diseño. Así que esta barra es algo de funcionalidad del lado del cliente, pero esta lista de géneros aquí es algo que querría obtener de la database. Y ahora mismo, si miro esto, main nav en algún lugar de aquí, tengo un selector de género justo allí. Esto de nuevo, utiliza useEffect, fetch para obtener las APIs, etc., de una manera muy tradicional. Así que quiero mover esto al cliente, pero no puedo simplemente porque hay mucho otro estado allí también. Hay un estado aquí para si el desplegable está abierto. En algún lugar de aquí, hay un botón que desencadena el hecho de que las películas están abiertas. Es este gatillo de popover, que es uno de esos componentes de ShadCN. Así que hay bastante de esto, que necesita funcionar en el cliente, pero también hay cosas como esta, que realmente querría hacer en el servidor. Y ahora mismo, esto no tiene una directiva useClient porque sus componentes padres, el, ¿dónde estaba? Diseño. Esto tiene la directiva useClient. Así que si borro eso y veo qué pasa, vería, en primer lugar, que el selector de género se queja. Así que hagamos de esto un componente de cliente. Pero incluso después de haber hecho eso, todavía obtendría otros, como el carrito de compras. No funciona. Así que esto está en el main nav, y acabo de tener eso abierto. ¿Dónde está? Ahí, main nav. Esto utiliza el carrito de compras, pero también utiliza los parámetros de búsqueda del nombre de la ruta. Así que esto es también típicamente algo que necesita funcionar en el cliente, no puede en el servidor. Así que necesito poner un useClient allí. Y ahora debería funcionar bien de nuevo. Pero eso no me ayuda realmente con el problema si quiero convertir esto en un componente de servidor o tal vez porque no puede ser un componente de servidor completo, me gustaría dividirlo en un cliente y un componente de servidor. Así que necesitamos hacer un poco más. Y para eso, voy a saltar un poco adelante. Esto, nos vamos a quedar sin tiempo. Y es algo útil de ver. Voy a ir y usar esta página por un momento. Marvin, ¿podrías por favor silenciar tu micrófono? Gracias. Así que aquí tengo algunos componentes, una página de servidor cliente, un componente padre y un componente hijo. Y voy a usar esos para demostrar cuál es el efecto de useClient y cómo se renderizan las cosas y cómo se componen. Porque ahora mismo no hay ningún useClient o cualquier cosa específica del servidor aquí en ninguno de los lugares. También todos tienen este mensaje de console.log donde realmente se renderizan. Ahora, si vuelvo aquí y abro la ventana de la consola, podemos ver que no hay mensajes aquí.

Renderizado del lado del servidor y Componentes del Cliente

Short description:

Al usar el renderizado del lado del servidor con Next.js, todos los componentes, ya sean componentes del cliente o del servidor, se renderizan en el servidor y se envían al navegador. Sin embargo, si un componente está marcado como un componente del cliente, comienza un límite del cliente, y cualquier componente renderizado a partir de él también se trata como un componente del cliente. Esto puede llevar a un comportamiento inesperado, como la ejecución de lógica específica del servidor en el cliente. Para resolver esto, se puede ajustar la jerarquía de componentes pasando el componente hijo como una prop al componente padre. Esto asegura que el componente hijo se renderiza en el servidor y se compone como un hijo del componente del cliente en el lado del cliente.

Así que permíteme refrescar esta página. No hay nada aquí, ningún mensaje en absoluto. Y si busco, digamos, tomaremos el componente hijo. Renderizando el componente hijo. Busqué eso, no se encontraron coincidencias. Así que ninguno de este código existe en el navegador.

Si cambio al servidor de desarrollo, en cambio podemos ver esos mensajes aquí mismo. Podemos ver aquí renderizando la página del servidor o cliente, renderizando el componente padre, renderizando los componentes hijos. Ahora, ¿qué pasa si tomo el del medio, el componente padre, y añado un useClient aquí? Así que estoy diciendo que este componente padre debería ser un componente del cliente, pero eso es lo único que voy a cambiar. Voy a guardar eso. Todavía vemos renderizando el servidor o la página del cliente, renderizando el padre y renderizando el hijo aquí. Así que todos todavía se renderizan en el servidor. Pero si vuelvo al navegador ahora, aquí también vemos renderizando el padre y renderizando el hijo. Y de hecho, lo vemos dos veces porque React en modo de desarrollo, en modo estricto, renderizará todos los componentes dos veces. Y si hago esta búsqueda de nuevo, ahora encontramos que este componente está disponible en el cliente. Pero no hice un cambio en los componentes hijos. No puse useClient allí. Así que sólo para mostrar eso de nuevo, el componente hijo completamente sin cambios. Entonces, ¿por qué se movió al cliente, al navegador, y por qué todavía obtenemos esos mensajes de renderizado aquí?

Bueno, comencemos con la última pregunta. ¿Por qué obtenemos estos aquí? Eso es puramente porque el renderizado del lado del servidor y next. Next renderiza todo del lado del servidor, ya sea un componente del cliente o un componente del servidor, y lo envía al navegador. Así que por eso todavía se renderizan aquí. Pero sin el renderizado del lado del servidor, no habría visto el componente padre, el componente hijo aquí. Sólo habría visto la página del servidor o del cliente aquí. Ahora, ¿por qué veo tanto el componente padre como el hijo aquí en el navegador, bien, donde sólo marqué los componentes padres como con useClient? Se llama una directiva del lado del cliente. Esto hace que esto sea un componente del cliente. Pero en realidad, es un poco más que eso. Hace que esto sea un componente del cliente, pero comienza un límite del cliente. Así que esto es un componente del cliente, pero cualquier componente renderizado desde este componente también se va a tratar como un componente del cliente. Así que si quito esto por un momento, y entro en los componentes hijos, y hagamos de esto un componente asíncrono, y realmente hago algo que no podría hacer en el cliente. Oh, espera. Prisma.findfirst o algo así. Y lo renderizaremos. Renderizaremos ese nombre. Ayuda si mi sintaxis es correcta. Si voy al navegador ahora, vemos que renderiza aventura aquí, que es el primer género que encuentra. Ahora esto funciona porque desactivé este useClient en los componentes padres, pero todavía puedo renderizarlo. En el componente padre, que hace que todo sea un componente del servidor de nuevo. Pero ahora lo introduciré de nuevo. Volvemos al navegador. Refresco y en realidad funciona, lo cual me sorprende un poco. ¿Por qué funciona esto? No debería. Eso es más como lo que... Bueno, todavía no es exactamente el error que esperaba, pero al menos obtengo un error ahora. No esperaba un appendChild. Esperaba esto. ¿Por qué mi ratón responde? Porque lo moví fuera de la alfombrilla del ratón. Así que obtengo un error aquí diciendo que Prisma Client no puede funcionar en este entorno de navegador. Es algo que sólo puede funcionar en el servidor. Así que esto claramente no funciona. Tengo un componente del cliente aquí y porque el componente hijo se renderiza desde un componente del cliente, se trata como un componente del cliente, aunque tenga lógica aquí, que pertenece a un componente del servidor. Entonces, ¿cómo podemos hacer que esto funcione? Bueno, vamos a tomar este, lo quitamos aquí por un momento, y vamos a la página, que también sigue siendo un componente padre. Mueve esto aquí, resuelve esa importación, y vuelve al navegador. Así que aquí se renderiza perfectamente bien, excepto que el anidamiento ya no es lo que queremos que sea. Excepto que el anidamiento ya no es lo que teníamos antes, porque ahora el componente hijo no está anidado dentro del componente padre, está debajo. Pero recuerda cuando expliqué que teníamos dos fases, teníamos la fase de renderizado, que es lo que está sucediendo aquí mismo, y tenemos la fase de composición donde determinamos qué es un hijo de qué y cómo se insertan las cosas en el DOM. Ahora, lo que puedo hacer es que puedo decir, quiero renderizarlo aquí, pero pasar esto al componente padre como un hijo. Ahora obtengo un error de compilación aquí, lo arreglaremos en un minuto. Ahora mismo, el componente hijo desaparece, pero no hay errores aparte de ese error de compilación. Y ese error de compilación es porque mi componente padre no sabe acerca de los hijos. Así que vamos y añadimos una prop aquí. Props con hijos. Así que eso es un tipo estándar de React, que define cómo se ven los hijos. Tomaré los hijos y renderizaré lo que sean los hijos debajo del encabezado con el componente padre. El error de compilación aquí se ha ido porque ahora el componente padre permite hijos. Y si vuelvo al navegador ahora, podemos ver que la página del servidor o cliente se renderiza, el componente padre se renderiza, el componente hijo se renderiza, y es capaz de cargar un género. Y en los mensajes, podemos ver que sólo el componente padre se está renderizando en el navegador, el componente del cliente ya no lo está. Se renderiza en el servidor y el DOM virtual resultante se inyecta en el componente del cliente y se compone como un hijo de ese componente del cliente. Pero esto se renderiza en el servidor y la composición ocurre en el cliente. Bueno, eso es bastante ingenioso.

Simplificando el Selector de Género y Usando Suspense

Short description:

Podemos simplificar el selector de género utilizando una consulta directa a la base de datos en lugar de buscar. El encabezado del sitio se convierte en un componente de servidor, lo que nos permite pasar los géneros. Podemos usar suspense para manejar el estado de carga y renderizar una interfaz de usuario de respaldo. El componente de servidor de React transmite datos al cliente, actualizando la interfaz de usuario y renderizando un componente de cliente de React.

Y esa es una buena forma de componer cosas juntas. Y eso es lo que podemos hacer con ese elemento de navegación. Quiero que los data para este desplegable sean una consulta directa, ya no más búsquedas, etc. Hacer eso más simple. Bueno, vamos a hacer eso.

Así que tenemos el selector de género. Quiero deshacerme de este estado de género y de este useEffect donde hacemos la búsqueda. Pero eso significa que necesitamos pasarlo o conseguirlo de alguna manera. Así que lo haremos con props. Así que este componente está contento, pero esto se renderiza desde el menú principal. Así que esto necesita saber sobre los géneros de alguna manera. Así que algo así, excepto que esto no puede cargarlos. Lo siento, esto no puede cargarlos directamente porque esto también es un componente de cliente. Así que vamos a tomar la misma definición de prop y la pondremos aquí. Así que esto muestra que está realmente disponible. Y vamos a resolver esto. Así que eso compila. Excepto que todavía necesita ser pasado a aquí. Así que eso está en el encabezado del sitio. Pero esto es algo que convertimos en un componente de servidor porque quitamos el useClient aquí. Así que aquí puedo pasar los géneros. Y ahora aquí, puedo hacer un par de cosas diferentes, pero sólo voy a hacer lo simple ahora. Voy a decir, const genres es 08 Prisma género.select, ¿qué es? FindMany. Y esto necesita ser una función asíncrona ahora, lo cual puede porque es una función de servidor. Y ahora cargamos estos géneros a través de una consulta directa a la database y no los ordené, pero ahora agregar una cláusula de orden aquí sería bastante simple. Ahora esto funciona.

El único inconveniente es que este encabezado del sitio es una función asíncrona. Y si esto tarda mucho tiempo, entonces todo el encabezado del sitio va a mostrar alguna interfaz de usuario de respaldo si suspendes. Así que toda la parte superior desaparece y quiero renderizar todo excepto esta carga por películas. Así que una forma un poco mejor es crear otro componente, un componente de carga, cargador de género. Aquí, haremos esa consulta y esto va a ser el asíncrono. Este ya no necesita ser asíncrono. No estamos haciendo una consulta allí. Aquí vamos a devolver al Selector de Género, pasando esos géneros. Y ahora en lugar de pasar los data aquí, sólo voy a pasar otro componente. Al igual que estaba usando hijos, en este caso lo estoy haciendo con un nombre específico, pero el efecto es el mismo. La tipificación es ligeramente diferente, sin embargo, así que los géneros ya no son una lista de data, es un nodo de React. Y aquí sólo quiero mostrar esa lista de géneros. Así que todo sigue funcionando, excepto que todavía no estamos usando suspense y déjame dejar claro que esto es lento. Vamos a poner un sueño aquí y tenemos que hacerlo realmente lento, cinco segundos. Así que ahora si refresco y en realidad va a ser mejor abrir esto en una nueva página. Vemos que no vemos nada, nada, nada hasta que han pasado esos cinco segundos y luego toda la página se renderiza porque todo se suspende. Pero ahora puedo empezar a usar suspense y decir, bueno, sólo quiero que esta parte se suspenda por sí misma. Fallback es cargando o algo así. ¿Por qué no funciona el autocompletado? ¿Por qué no funciona el autocompletado? Porque esto necesita ser cerrado. Así que ahora si refresco, ves primero la carga allí y luego después de que pasan cinco segundos sólo este componente se resuelve y todo está bien. Y la interfaz de usuario no es muy bonita, pero podemos hacerla mucho más bonita si cogemos este botón. Así que toma el botón que normalmente se renderiza y lo usaremos como la interfaz de usuario de respaldo. En lugar de la mayoría de las cosas, sólo voy a renderizar el predeterminado y vamos a deshacernos de todo esto, no lo necesitamos. ¿Qué hice mal? ¿Por qué no, no le gusta algo, pero no estoy seguro de por qué. Oh, porque open está indefinido. Así que ahora se renderiza y lo único que queremos hacer es decir, esto está desactivado mientras es el respaldo. Así que ahora en el navegador, si presiono F5, vemos este desplegable dentro de un estado de botón desactivado y después de cinco segundos, es más fácil de ver por el Chevron que aparece. Como si refresco, no hay Chevrons, no hay desplegable, no hace nada hasta después de algún tiempo se resuelve. Así que tenemos un componente de servidor de React transmitiendo con data después de cinco segundos, actualizando la interfaz de usuario, renderizando un componente de cliente de React, lo cual creo que es bastante dulce.

Pregunta de Radek, adelante. Sí, gracias por este caso de uso. Sólo estoy tratando de ordenarlo en mi cabeza. Así que si lo comparo con, digamos, la carga perezosa tradicional desde el navegador y digamos, me enfoco en el punto de vista de la user experience. Así que en este caso, no hay como una llamada API. Todo sucede en el servidor internamente. Y luego una vez que los géneros están listos, se transmiten de vuelta al navegador. Pero desde el punto de vista de la user experience, no hay diferencia. El usuario todavía necesita como esperar para la completitud de la solicitud. Sí, eso es correcto. Así que puedes mostrar algo como un esqueleto o estado de carga, lo que sea. Así que desde el punto de vista del usuario, no hay diferencia, ¿verdad? Así que es sólo una forma diferente de cómo entregar la pieza de funcionalidad al navegador. Sí, eso es correcto. Vale, lo tengo, lo tengo. Gracias.

Componentes de Servidor y Acciones de Servidor

Short description:

Prefiero este método porque elimina la necesidad de solicitudes fetch, mejora el almacenamiento en caché y oculta las llamadas API del navegador. El paquete solo para servidor es útil para prevenir el uso de componentes de servidor en el lado del cliente. Proporciona errores en tiempo de compilación en lugar de errores en tiempo de ejecución. Las acciones del servidor simplifican los formularios de entrada de datos al eliminar la necesidad de JavaScript en el cliente. En lugar de escribir código complejo, podemos manejar las presentaciones de formularios directamente en el servidor.

La razón por la que prefiero este método es porque, de nuevo, me he deshecho de la solicitud fetch aquí. Así que estoy obteniendo los géneros de manera más directa y sin serialización, deserialización. Tengo un mejor almacenamiento en caché, etc. Sí, y en realidad, bueno, en realidad ocultas las llamadas API. Así que ya no expones tus llamadas API al navegador, ¿verdad? Sí. Bueno, todavía hay una llamada API yendo a la database, por supuesto, pero no hay una llamada API RESTful. No hay forma de que alguien desde un navegador pudiera solicitar lo mismo. Sí, sí, sí. Todavía tengo estas solicitudes de géneros aquí, ¿verdad?, eso no es la API, aquí, pero podría eliminar esto, como ya no se usa. Puedo eliminar esto y todo funcionaría perfectamente bien. Y no había forma desde el navegador de que pudieran llegar a esos data o potencialmente si hubiera una actualización allí, hacer un post, etc. Eso es lo que quería decir. Sí, gracias.

Bueno, en realidad combiné un par de las diferentes demostraciones aquí. Así que eso fue la navegación, la primera parte, luego hice eso. Una cosa que no mostré es este paquete solo para servidor, que es realmente útil. Si tienes el componente de servidor y accidentalmente lo usas desde el cliente, entonces obtendrás, o al menos probablemente obtendrás un error en los clientes de que estás ejecutando algo que no puedes hacer. Pero hay casos en los que es posible que no veas ese error. Y aún así, es mejor obtener un error así en tiempo de compilación, en lugar de en tiempo de runtime. Así que hay un paquete llamado solo para servidor y puedes agregarlo a cualquier componente que solo debería estar disponible en el servidor. Ahora, este no es uno de esos pero déjame agregarlo aquí para mostrarte qué pasa. Así que si agrego solo para servidor aquí, inmediatamente veo un error aquí. En primer lugar, esto está marcado, reduce cliente. Así que no le gusta eso. Y aquí, también obtengo tu componente de importación que necesita solo para servidor, y no puedes hacer eso. Ahora, lo interesante es que podría agregar esto a componentes que deberían ser solo para servidor, como por ejemplo, tenía un componente hijo aquí donde estoy haciendo un fetch. Así que podría agregar eso aquí. Pero como esto es solo una importación, en realidad puedo ir un paso más allá y decir aquí en el archivo Prisma, decir, bueno, cualquier código que importe este archivo solo es capaz de ejecutarse en el servidor porque esto es alrededor del cliente Prisma funcionalidad del lado del servidor. Así que esto simplemente lanzará un error. Así que esto está bien ahora, sin problema. Pero si hiciera esto en un componente de cliente, déjame poner un uso cliente aquí. Ahora, inmediatamente obtendré este error porque estoy importando Prisma, usándolo. Y Prisma está indicado como solo siendo capaz de servidor. Indicado como solo siendo capaz de servidor. Corregir error. Así que es un paquete bastante útil para agregar como un marcador a código que no puede ejecutarse en el cliente y obtendrás tiempo de compilación, error de tiempo de construcción antes de que obtengas un error en tiempo de ejecución de que algo no funciona. Y en realidad he visto casos con componentes de servidor de React que eran asíncronos, que accidentalmente se renderizaron en el cliente donde no había un error porque algo no podía correr como esto. Pero todavía era asíncrono y los componentes del cliente deberían en este momento nunca ser asíncronos. Hay planes para hacer que los componentes del cliente también sean asíncronos, pero ahora mismo eso no es un escenario soportado. Así que con esta importación, puedes evitar que eso suceda.

Entonces, acabamos de ver la composición que demostré donde podríamos pasar un componente de servidor como un hijo de un componente de cliente. Es solo una cuestión de dónde ejecutamos el RITS. Esta demostración, donde renderizamos componentes hijo dentro de la página padre y pasando a un componente padre del navegador hijo que es bastante genial. Así que hicimos eso. Y luego la parte importante, por qué realmente queríamos hacerlo cargando los géneros en el servidor. Así que sugiero, voy a saltarme el código. Acabas de verme hacer esto en la diapositiva. Así que solo sugiero que vayas y hagas esto. Es el último ejercicio que realmente vamos a hacer. Después de eso, voy a mostrar brevemente las acciones del servidor porque nos estamos quedando sin tiempo, pero eso está bien. No hay problema. Porque todavía tienes todos los ejercicios y puedes ver el curso donde muestro todo esto y profundizo más en ello de todos modos, si quieres. Así que déjame demostrar rápidamente cómo las acciones del servidor entrarán en juego porque creo que son algo menos destacadas pero también una capacidad muy ordenada que obtenemos que es parte de la especificación de componentes de servidor de React. Así que esto no es específico de Next.js, lo que algunas personas piensan. Originalmente pensé eso también, pero esto estará disponible en otras pilas de React cuando también soporten componentes de servidor de React. Pero la cosa es que tradicionalmente, si haces, digamos, forms de entrada de data en el cliente, necesitas escribir código allí. Típicamente manejas el onSubmitEventHandler en el formulario y haces cosas allí. Eso también significa que siempre tienes que tener JavaScript habilitado en el cliente. De lo contrario, simplemente no funcionaría. Pero con las acciones del servidor de React, podemos hacer eso mucho más simple y gran parte de la magia desaparece. En lugar de escribir un manejador onSubmit, haciendo preventDefaults, recogiendo los data, haciendo algún tipo de solicitud post al backend, obteniendo los data allí de la solicitud y haciendo algo, podemos hacer todo eso mucho más directamente. Donde voy a hacer eso es con los géneros. Tengo la lista de géneros aquí. Suponiendo que esto todavía se carga. Ahí está. Tenemos un formulario de edición. Solo hay un nombre allí. Así que realmente no hay mucho que editar. Y ahora puedo hacer clic en guardar cambios pero en realidad no pasa nada. Bueno, casi nada.

Cambiando Acciones y Enviando Formularios

Short description:

Cambié la acción a 'acción uno' y guardé los cambios. En la página de géneros, tenemos una página de servidor que importa 'solo servidor'. Busca el género específico y muestra el formulario. El formulario de género utiliza componentes de cliente y tiene un manejador de envío que se envía al backend e imprime un mensaje en la consola.

De hecho, si cambio esto un poco, digamos acción uno, hago clic en guardar cambios. Vemos que hay un mensaje aquí en la consola que dice que el nombre se ha convertido en acción uno. Permíteme cerrar todos estos y vamos a la página de géneros. Esta. Podemos ver que esta es una página de servidor. Importa 'solo servidor' para dejarlo realmente claro. Busca el género específico que nos interesa y luego muestra el formulario. Y el formulario de género, podemos ver que utiliza componentes de cliente. Tiene un manejador de envío aquí, que es más o menos lo predeterminado excepto que realmente se envía a un backend. Simplemente imprime un mensaje en la consola y está conectado a ese formulario de envío.

Manejo de Acciones del Servidor y Redirección

Short description:

Ahora no podemos deshacernos de use client, pero podemos convertirlo en una acción. Los parámetros serán ligeramente diferentes. Necesitamos marcar la función con use server y hacerla asíncrona. El cierre provoca que se muestren valores diferentes. Podemos llamar a una función para guardar los datos del formulario y actualizar el género. También podemos redirigir a otra página utilizando la navegación de Next.

Ahora, realmente no podemos deshacernos de use client aquí porque si lo hacemos, obtendremos un error. Ya podemos ver el error aquí. Es que onSubmit no puede ser una función porque ahora esto se renderiza como un componente de servidor porque se renderiza desde otros componentes de servidor. Pero puedo convertir esto en una acción. Resulta que los parámetros van a ser ligeramente diferentes. Así que deshagámonos de este tipo y los parámetros ya no son un evento sino que obtendrán form data, que es de tipo form data. Así que podemos deshacernos de estos dos. El error de compilación desaparece, pero todavía vemos en la consola que hay un error aquí que no puede ser marcado, que la función no puede ser pasada directamente. Tiene que ser marcada con use server. Así que use server solo funciona en acciones de servidor, no en componentes de servidor. Pero puedo especificar esta función como un use server. Así que no lo estoy poniendo en la parte superior del archivo, lo cual también es posible en otros casos. Pero en este caso, estoy especificando que esta función específica debe ser ejecutada en el servidor. Lo guardaré de nuevo. Y debería ver otro error, que está aquí, que dice que las acciones del servidor deben ser funciones asíncronas. Así que hagamos esto asíncrono. Y ahora el error debería desaparecer y debería estar contento. Así que volveremos a llamar a esto acción dos. Haré clic en guardar cambios y no hay más mensajes aquí en la consola. Pero si vuelvo al servidor, de repente vemos un mensaje de guardado. De repente vemos un mensaje de guardado de género aquí. Guardando género 28 acción. Y aquí realmente dice, vale, el nuevo valor que pasaste es acción dos. ¿Por qué los valores diferentes? Aquí arriba dice acción, no acción dos. Aquí abajo dice acción dos. Bueno, eso es debido a un cierre. Así que aquí, tengo el género original y el que estoy imprimiendo abajo en la tabla es este es el del form data actual. Así que en realidad no quiero hacer esto. Simplemente imprimamos los data de allí. Pero ahora tengo estos form data y en realidad puedo ir y llamar a una función para guardar esto. Tengo una función de guardar género. Y puedo pasar un objeto de género allí. Así que convirtamos estos form data en la forma correcta. Y veamos si IntelliSense lo completa por mí. No, no lo hace. Consigue el ID. Y una cadena porque puede haber diferentes tipos. Y esto en realidad necesita ser convertido a un número. Y tiene que haber un nombre allí. Y también necesitamos convertir eso en una cadena. Y esto es de tipo género. Eso no es muy fácil. Me faltaba una coma allí. Ahora puedo pasar el género y en realidad quiero esperar eso porque es una acción asíncrona. Así que guardar género, lo siento. Guardar género es muy simple. Y simplemente va directamente y llama a updates en géneros para actualizar ese género específico. Así que ahora he incrustado la lógica para hacer la actualización. En realidad podría haber usado Prisma directamente aquí también. Y he incrustado la lógica para usar insights de un componente que se usa desde el cliente. Ahora veamos si puedo actualizar cosas. Género tres, guardar cambios. Aquí vemos que acción tres, un género apareció. Y si vuelvo a la lista, vemos inmediatamente que es género tres. Vuelvo aquí. Y esto no se actualizó, todavía necesita eso dinámico. Pero otra cosa interesante que podemos hacer es en una de estas acciones de servidor, en realidad podemos redirigir a otro lugar. Así que podría llamar a redirigir y decir, quiero volver a la lista de géneros. Géneros se llama. ¿Y por qué no redirige? Eso no es de donde se supone que debe venir. Debería venir de la navegación de Next. Lo interesante ahora es que supongamos que cambio de nuevo a cuatro, hago clic en guardar cambios. Hace las actualizaciones y debería. Tomó un poco más de tiempo del que esperaba, pero cuando termine, debería actualizar. La razón por la que en realidad tardó más es porque en realidad decide que necesita volver a consultar estos data. Y todavía había un sueño allí. Así que déjame deshacerme rápidamente de ese sueño. Ella no estaba aquí, pero estoy seguro de que puedes verla. Ella no estaba aquí, pero aquí, esta. Eso lo hace lento.

Prueba de la Funcionalidad del Formulario

Short description:

Probemos la funcionalidad del formulario incluso con JavaScript desactivado. El formulario está configurado para publicar de nuevo en la URL actual, codificando los datos del formulario. La solicitud se envía con una redirección a la lista de géneros, lo cual no era posible antes.

Entonces, hagamos esto de nuevo. Ahora debería ser más rápido. Acción cinco, los cambios guardados fueron redirigidos de nuevo. Esta es la acción cinco. Y también aparece correctamente aquí. Ahora, lo interesante es que, supongamos que desactivo JavaScript, esto seguirá funcionando. Vamos a la página de inicio con JavaScript desactivado, refrescamos, asegurémonos de que no estás ejecutando cosas obsoletas. Voy a géneros, acción cinco. Cambié esto a acción seis, guardar cambios. Y todavía está actualizado. Todo eso sigue funcionando con JavaScript desactivado. Si miro detrás de las escenas, si bajamos aquí en algún lugar hay un formulario aquí. Entonces aquí puedes ver que el formulario en realidad tiene un par de propiedades adicionales establecidas, acción, tipo de codificación y el método. Entonces la acción está establecida, pero vacía, lo que significa que en realidad publica de nuevo en la URL actual, codificando que son datos de formulario data y que debería usar un post en lugar del get predeterminado. Entonces, si miro la red, hagamos clic en conservar registro, hago guardar cambios. Deberíamos ver esa solicitud aquí. Aquí podemos ver que los data están siendo enviados y hay una redirección siendo enviada. ¿Qué era? Devuelve una redirección 303 de vuelta a la lista de géneros, lo cual creo que es realmente genial. Algo que no era posible antes. Entonces aquí está ese ejemplo, vamos a saltarnos el ejercicio porque ya estoy pasando el tiempo. Otra capacidad agradable de la que no voy a hacer una demostración, solo voy a contarte, es que como es solo una función, puedes llamar a esa función tú mismo. Así que tengo un ejemplo aquí con un carrito de compras. Hay un carrito de compras para pagar, que está siendo llamado por la función, hay un carrito de compras para pagar, que está siendo llamado. Y ahora mismo con el código, solo se llama en el cliente, pero al agregar el servidor, en este caso, lo he añadido al archivo, no a la función, cualquiera de las dos funcionaría. En realidad movió esta función al servidor y el transporte de red se hace automáticamente. Así que en el cliente en los envíos del formulario de pago, todo lo que hago es esperar, llamar a esa función. Y esto en realidad hace un post HTTP detrás de las escenas, serializa los data, deserializa los data, obtiene la respuesta de vuelta. Podría devolver algo de esa función. Puedo lanzar un error allí y atraparlo aquí mismo en ese try-catch. Todo eso simplemente funciona. La única cosa que realmente necesitas tener en cuenta, parece que solo estás llamando a una función, pero en realidad, estás haciendo un post HTTP. No ves nada de eso, pero estás haciendo un post HTTP. Así que aquí en el código del servidor, asegúrate de hacer la validación adecuada. ¿Está el usuario conectado, etc.? ¿Tiene permiso para hacer esto? Porque al final, es un post HTTP. Cualquiera con scripts curl podría hacer esto o simplemente con un par de scripts, con fetch o algo así. Así que asegúrate de que es seguro. Así que mira en la demostración que, algunas recomendaciones generales como crear componentes compartidos, lo que básicamente significa que no dependen del servidor o de la funcionalidad del cliente y se ejecutarán donde sea necesario. Podría ser cliente, podría ser servidor. Usa el servidor donde sea necesario. Que es típicamente más rápido. Usa clientes donde sea necesario cuando uses el estado local, APIs del navegador, etc. Porque en este momento estás un poco limitado a Next.js, aprende sobre las capacidades de Next.js. Necesitas usar el enrutador de la aplicación. Estudia sobre la caché porque eso puede hacer la vida un poco más difícil. Así que en conclusión, los Componentes de Servidor de React son una gran nueva adición a React. Creo que hace posibles muchas nuevas capacidades para React. Es diferente, no es un requisito. Puedes seguir usando React de la manera que siempre lo hiciste si quieres. Pero abre muchas nuevas posibilidades y mantiene a React en la vanguardia de lo que está sucediendo. Muy bonito. Ten en cuenta que necesitas un servidor en este momento. Eso significa Next.js en el futuro. Eso significará otros como Remix, cosas como eso, Waku. Use client es un límite del cliente, no per se un componente del cliente. Cualquier componente renderizado desde un componente del cliente también será tratado como un componente del cliente. Mira las acciones del servidor. No reciben casi tanta atención, pero las acciones del servidor son realmente agradables. E incluso si no usas los Componentes de Servidor de React, todavía puedes usar las acciones del servidor, lo cual es realmente agradable. Así que con eso, estamos al final. Un poco más de tiempo. Lo siento por eso. Espero que hayas aprendido algo. Si quieres aprender más sobre React, puedes ir a la siguiente diapositiva. Lo siento por eso. Gracias por unirte. Si alguien quiere hacer alguna pregunta final, siéntete libre de hacerlo ahora. Solo desactiva tu micrófono y adelante. De lo contrario, siempre puedes enviarme un correo electrónico o un Tweet más tarde. Tienes un código de cupón gratuito para el curso que recientemente publiqué, que cubre todo este material y luego más. Y luego voy a añadir más a eso. Como no he añadido pruebas unitarias, por ejemplo, al curso todavía, lo que planeo hacer. No he añadido trabajar con bibliotecas heredadas a ese curso todavía. Eso es otra cosa que planeo añadir porque hay mucho contenido alrededor de aquí, que es interesante y necesitas tener en cuenta. Gracias por asistir. Gracias por gustarle la masterclass. Espero que te guste el curso también. Y si lo haces, por favor dale una revisión de cinco estrellas. Eso ayuda a otros a encontrarlo también.