Fundamentos de Remix

Rate this content
Bookmark

Construir aplicaciones web modernas está lleno de complejidades. Y eso es solo si te molestas en lidiar con los problemas.


¿Cansado de conectar onSubmit a APIs en el backend y asegurarte de que tu caché del lado del cliente esté actualizada? ¿No sería genial poder aprovechar la naturaleza global de CSS en tu beneficio, en lugar de buscar herramientas o convenciones para evitarlo o solucionarlo? ¿Y qué tal si tuvieras diseños anidados con una gestión de datos inteligente y optimizada para el rendimiento que simplemente funciona™?


Remix resuelve algunos de estos problemas y elimina por completo el resto. Ni siquiera tienes que pensar en la gestión de la caché del servidor o en los conflictos de nombres de espacio global de CSS. No es que Remix tenga APIs para evitar estos problemas, simplemente no existen cuando estás usando Remix. Ah, y no necesitas ese enorme y complejo cliente de GraphQL cuando estás usando Remix. Ellos te tienen cubierto. ¿Listo para construir aplicaciones más rápidas?


Al final de este masterclass, sabrás cómo:

- Crear rutas de Remix

- Estilizar aplicaciones de Remix

- Cargar datos en los loaders de Remix

- Mutar datos con formularios y acciones

136 min
04 Jul, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Remix simplifica la gestión del estado y la carga de datos en aplicaciones web, combinando el desarrollo web moderno con la simplicidad de gestionar el estado en el backend. Admite enrutamiento anidado y proporciona una forma conveniente de asociar componentes padre e hijo basados en segmentos de URL. Remix maneja la obtención de datos, las mutaciones y los estados de error automáticamente. Ofrece flexibilidad para acceder a los datos de los loaders y permite múltiples instancias de datos de loader en un componente. Remix también proporciona un manejo perfecto de las actualizaciones de formularios, el manejo de errores y las redirecciones.

Available in English

1. Introducción a Remix y Ejercicio 1

Short description:

Bienvenidos a todos. Vamos a hablar sobre Remix y cubrir temas como enrutamiento anidado, carga de datos, parámetros dinámicos, mutaciones y mejora progresiva. En el Ejercicio 1, agregaremos un enlace a la ruta de publicaciones en Indy Stack. Repasaremos el README y nos detendremos en la carga de datos. Luego, crearemos una ruta de índice de publicaciones en nuestro directorio de rutas. Se recomienda TypeScript para construir aplicaciones web con Remix, pero no es obligatorio. ¡Comencemos!

Bienvenidos a todos. Estoy muy emocionado de hablar con todos ustedes sobre Remix. Creo que es increíble y creo que todos vamos a pasar un buen rato aprendiendo sobre Remix. Permítanme preparar mi pantalla. Este es el repositorio del masterclass, y esto es el masterclass ejecutándose localmente. Permítanme aumentar un poco eso aquí, moverlo un poco. Aquí está nuestro esquema. No vamos a cubrir todo esto. Solo tenemos tres horas, así que trabajaremos en algunas cosas. Quiero darles tiempo para que practiquen en el teclado, pero debido a que tenemos poco tiempo, tengo la sensación de que están más interesados en mí o en cubrir más contenido que en pasar mucho tiempo con sus manos en el teclado. Esa es mi suposición. Esa es la suposición con la que voy a trabajar. Por lo tanto, debido a eso, les daré un poco de tiempo para algunos de estos como ejercicios, pero la mayor parte del tiempo solo estarán observando y haciendo preguntas en Discord. Y creo que ese será el mejor uso del tiempo limitado que tenemos.

Hoy hablaremos sobre enrutamiento anidado, carga de data, parámetros dinámicos, enrutamiento anidado, mutaciones, mejora progresiva y luego hay tareas, todo tipo de cosas que podemos hacer para las tareas. Algunas de estas cosas las revisaremos rápidamente y otras las exploraremos más a fondo. Así que quiero darles una introducción a lo que es Remix y su propuesta de valor única y todo eso. Pero me gustaría comenzar más rápido. Y así que creo que vamos a hacer el primer ejercicio y luego volveremos y haremos un poco de qué es Remix. En realidad, esto es parte de mi estrategia de aprendizaje. Es como lanzarte al agua. Así que vamos a comenzar con el Ejercicio 1 y en realidad no van a ingresar a este directorio. La forma en que funciona es que tenemos un script especial llamado route runner. Entonces esto se llama dev, que puedes ejecutar, NodeDev y luego le das la ruta del ejercicio que deseas y se ejecutará ese ejercicio y lo interesante de esto es que se ejecutará en un puerto asociado al ejercicio. Entonces puedes ejecutar todos los ejercicios y todas las versiones terminadas de los ejercicios en el mismo y todos funcionarán, lo cual es divertido y genial. Entonces, si ejecutas NodeDev exercise cero uno routing, y en realidad un consejo rápido, puedes simplemente hacer cero uno y eso también funcionará para que no tengas que escribir todo, pero luego abres Locos 4001 y se te presenta esta página que es el Indy stack. Entonces Remix tiene esta función de generación de proyectos donde puedes generar nuevos proyectos y los llamamos stacks. Tiene un montón de herramientas y cosas preinstaladas y preconfiguradas para ti. Y el tutorial que estamos siguiendo se basa en el Indy Stack. Entonces ahí es donde vamos a comenzar con el ejercicio uno, básicamente con un Indy Stack pregenerado y tu tarea para este ejercicio es simplemente agregar un enlace aquí, justo debajo de la gran imagen aquí, para llevarte a la ruta de publicaciones. Vamos a agregar un blog a este sitio. Eso es lo que vamos a hacer. Ese es tu primer ejercicio. Vas a ingresar a exercise 01 routing, ir al README y esto te dará un punto de partida y un punto de detención en el tutorial del blog. Entonces comenzarás con tu primera ruta y te detendrás justo cuando llegues a la carga de data. Así que no continuarás con la carga de data, te detendrás aquí para este ejercicio. Y así vamos a colocarlo en nuestro archivo index.j.s. Así que esta es nuestra página de inicio. Ahí es donde queremos que vaya. Y lo vamos a poner justo ahí. No importa realmente dónde esté porque no estamos aprendiendo jsx y la estructura adecuada o lo que sea. Eso no importa realmente. Así que venimos aquí. Tenemos un enlace a la publicación del blog. Y cuando hago clic en ese enlace, obtendremos un 404 porque aunque realmente estamos yendo a esa URL, en realidad no hay nada allí. Y dato curioso, porque Remix se renderiza en el servidor, en realidad obtienes un 404 del servidor al ir a esa página, todo lo que hemos estado haciendo en el cliente durante los últimos seis a ocho años. Cuando tienes una ruta que no es compatible, obtienes el HTML de índice. Así que obtienes un 200. Y el cliente simplemente dice: Oh, no podemos encontrarlo. Pero Remix, debido a que se renderiza en el servidor, puede dar un código de estado adecuado, lo cual es realmente bueno para el SEO y para que el navegador se comporte de la manera correcta y todo eso. Así que eso es bueno. Pero queremos tener algo allí. Y en el siguiente paso aquí, creamos una nueva ruta, y eso se controla teniendo una nueva ruta. Y eso se controla teniendo un archivo en posts. Y queremos tener el índice para nuestras publicaciones. Así que crearemos una ruta de índice de publicaciones en nuestro directorio de rutas. Así que vamos a crear posts y luego index.tsx. Y, por cierto, asumo que todos estamos usando TypeScript. TypeScript es la forma en que se construyen las aplicaciones web en estos días. Y si no estás familiarizado con TypeScript, te alegrará saber que en realidad no hay muchas rarezas de TypeScript que debas hacer con Remix. Hay un poco. Pero sí, es muy agradable. Entonces, si no estás acostumbrado a TypeScript, puedes omitir los tipos y aún funcionará. Solo verás pequeñas líneas rojas en algunos lugares. No es gran cosa. De acuerdo, solo vamos a copiar esto porque nuevamente, no creo que quieras pasar tiempo escribiendo jsx, pero lo importante aquí es que nuestro módulo exporta por defecto un componente de función. Supongo que podría ser un componente de clase. No sé por qué distingo con función, pero exportas una función o un componente. Y, y

2. Integración de Remix y React Router

Short description:

Aquí están las publicaciones. Tenemos este enlace a la ruta de publicaciones y luego las publicaciones son un archivo dentro de las rutas llamado, con una exportación predeterminada de lo que se debe renderizar cuando estamos en esa ruta. Esto sería con la convención que actualmente tenemos para Remix en la estructura de archivos, simplemente puedes tener un archivo posts.TSX. Remix utiliza React Router, Remix proviene de los creadores de React Router. Remix solo está utilizando React Router aquí. Remix se enfoca en los estándares web y en la experiencia de usuario de las aplicaciones web modernas. Remix toma las cosas que funcionaron muy bien en la web hace 10 años y luego las mezcla con las cosas que funcionan muy bien en la web moderna. Lo que molesta a las personas que han estado involucradas en la web durante mucho tiempo acerca de la web moderna es lo difícil que es construir un sitio web en estos días. Lo que Remix logra hacer es, lo que nos gustaba de la forma anterior de construir sitios web es que no tenías que preocuparte por administrar el estado en el navegador.

Esto es lo que se va a renderizar cuando el usuario llegue a la página de publicaciones. Aquí están las publicaciones. Y eso es todo, ese fue todo el ejercicio, simplemente agregar un enlace usando este componente de enlace que proviene de Remix. Y esto es en realidad simplemente siendo reexportado esencialmente desde React Router. Hay algunas características adicionales pero en su mayor parte solo se está reexportando. Y de hecho, las características adicionales se están moviendo a React Router propiamente dicho. De todos modos, tenemos este enlace a la ruta de publicaciones y luego las publicaciones son un archivo dentro de las rutas llamado, con una exportación predeterminada de lo que se debe renderizar cuando estamos en esa ruta. ¿Podría esa carpeta de publicaciones ser simplemente un archivo post.TSX o tiene que ser un archivo de índice? Buena pregunta. Sí, sí. Así que vamos a hacer esto ahora. Esto sería con la convención que actualmente tenemos para Remix en la estructura de archivos, simplemente puedes tener un archivo posts.TSX, así que podríamos poner todo esto aquí dentro y obtendríamos el mismo resultado y, por supuesto, podría eliminar esto o lo que sea, pero en los próximos ejercicios, también vamos a tener post/slug con el nombre del post y así que eventualmente vamos a necesitar tener el directorio de publicaciones. Y así, esto es efectivamente la página de inicio para el post, así que la página de índice para el post y eso es con lo que acabamos de comenzar, la página de índice. Pero no es necesariamente incorrecto tener este archivo porque podría haber algún tipo de navegación especial o pie de página que desees para todas tus publicaciones y eso es lo que pondrías aquí. Hablaremos más sobre eso cuando lleguemos al enrutamiento anidado, haciendo la interfaz de usuario del administrador, pero solo para darte un ejemplo rápido de lo que es esto, esto sería la ruta principal de esta ruta de índice y todas las rutas dentro de este directorio de publicaciones y los padres deben decir dónde se deben renderizar los hijos y la forma en que lo hacemos es a través del componente outlet de Remix ejecutando React. Y ahora puedo decir renderizar mi outlet y lo envolveré en un div y diré aquí está mi contenido del pie de página y mi contenido del encabezado y luego venimos aquí y tengo mi contenido del encabezado, las publicaciones, esta es la ruta de índice que proviene de nuestro índice justo aquí, eso justo ahí y luego nuestro contenido del pie de página. Y así ahora cada ruta dentro del directorio de publicaciones va a tener el contenido del encabezado y envolverá cualquier ruta secundaria. Y eso es realmente útil y ahora esto está controlando parte del diseño para nosotros. Y luego simplemente diciendo dónde se deben renderizar los hijos. Pero realmente no queremos envolver nada. Así que solo haremos esto y ahora lo que estamos viendo es en realidad la ruta principal predeterminada. Entonces, si no tienes una ruta principal, esto es básicamente nada. Es una estructura de enrutamiento similar a React Router 6, que tiene outlet y puede poner algo de enrutamiento dentro de ellos y tener padres. ¿Es algo así?

Sí, eso es exactamente lo que es. Remix utiliza React Router, Remix proviene de los creadores de React Router. Y así es, React Router está obteniendo muchas características geniales de Remix muy pronto. De acuerdo. Gracias. Sí, de hecho, hace un par de meses, tal vez un par de semanas en nuestro blog, escribimos esta publicación llamada Remixing React Router, donde estamos tomando muchas de las características realmente geniales de React Router y llevándolas a, simplemente dejaré un enlace a eso en Discord, llevándolas a. o muchas de las características de Remix a React Router. Y de hecho, podríamos titular esta publicación de manera diferente y en lugar de decir Remixing React Router, podríamos decir Unreacting React Router porque básicamente estamos tomando todas, estamos tomando todas estas características de Remix y poniéndolas en React Router. Simplemente estamos separando las características principales de Remix y React. Y lo que eso nos permitirá hacer es que ahora React Router es un adaptador para el enrutador de Remix, y luego podemos hacer adaptadores para Vue, Angular, Svelte, Preact y todas estas cosas. Entonces, en realidad, todo el mundo va a poder aprovechar Remix, independientemente de qué biblioteca de interfaz de usuario decidas usar, lo cual es bastante significativo. Entonces, en la versión futura, y tenemos esto en prelanzamiento en este momento, estamos pensando en lanzarlo esta semana o la próxima semana, donde tendremos el enrutador de Remix, y luego solo adaptadores para ese enrutador, lo cual es genial. Y los miembros de la comunidad ya están construyendo adaptadores para el enrutador de Remix, para Vue, Angular, Svelte y Preact. Y creo que puede haber otro, no recuerdo cuál, pero, sí, tiempos emocionantes, y sí. Así que definitivamente, Remix solo está utilizando React Router aquí.

Tengo una pregunta muy básica, tal vez, como Remix se ejecuta en el backend, no en el frontend, como, si tuvieras una aplicación React normal, se ejecutaría en el frontend como una aplicación de página única, pero Remix se ejecuta en el servidor Node o algo así, ¿verdad?

Sí, sí, pero es una SPA, una aplicación de página única cuando se hidrata, y así que si vienes a tu página de inicio, eso es todo, como esto se renderiza en el servidor, miras el código fuente y ves, como, todo el HTML y todo eso, pero cuando navegas a las publicaciones del blog, no obtienes una recarga completa de la página ni nada, simplemente cargamos el JavaScript necesario para esa página, y haremos lo mismo con el CSS y los datos y todo lo demás también. Así que es una transición del lado del cliente que está sucediendo aquí, por lo que obtienes transiciones de página, gestión de enfoque, todas esas cosas.

Ahora que hemos hecho el primer ejercicio, quiero tomar un momento para hablar sobre qué es Remix, y esta cosa con la que acabas de jugar por un segundo, así que Remix se enfoca en los estándares web y en la experiencia de usuario de las aplicaciones web modernas. Podrías decir que estamos mezclando lo antiguo con lo nuevo, y así que en Discord, voy a decir levanten la mano, levanten la mano, aquí, moveré esto para que todos puedan ver lo que estoy haciendo. Si llevas en desarrollo web nueve años o más, nueve, ahí vamos. Si llevas nueve o más, entonces pon nueve, de lo contrario pon ocho o siete o sí, el número, ya lo entiendes. Para mí, comencé en desarrollo web oficialmente en 2014. Así que eso me da ocho. Así que ahí vamos, genial. De hecho, tenemos bastantes personas que llevan nueve años o más. Veamos. Entonces, para aquellos de ustedes que llevan nueve años o más, esto les resultará muy familiar y cómodo porque Remix toma las cosas que funcionaron muy bien en la web hace 10 años y luego las mezcla con las cosas que funcionan muy bien en la web moderna en estos días. Entonces, lo que molesta a las personas que han estado involucradas en la web durante mucho tiempo acerca de la web moderna es lo difícil que es construir un sitio web en estos días. Hay tantas cosas que tienes que hacer. Tienes tus herramientas de construcción, tienes tus linters y formateadores, y tienes tu JSX, y tienes tus cosas de JavaScript. Y ahora tienes que administrar el estado en la interfaz de usuario y tantas cosas que tienes que hacer en estos días que no tenías que hacer antes. Y siempre me convencía y decía, bueno, sí, pero nuestras aplicaciones son mucho mejores de lo que solían ser. Podemos hacer mucho más de lo que solíamos poder hacer antes. Y sí, eso es cierto. El navegador es mucho más capaz. Buena suerte construyendo Figma a fines de los 90 o principios de los 2000. Sí, eso es absurdo. Así que eso es lo que siempre me convencía. Pero lo que Remix logra hacer es, lo que nos gustaba de la forma anterior de construir sitios web es que no tenías que preocuparte por administrar el estado en el navegador. Todo el estado básicamente vivía en la base de datos y tal vez pondrías una caché en algún lugar para que las cosas fueran más rápidas.

3. Simplificando la Gestión del Estado con Remix

Short description:

Remix simplifica la gestión del estado en aplicaciones web al proporcionar un modelo mental similar a los viejos tiempos cuando el estado vivía en la base de datos. Combina las capacidades del desarrollo web moderno con la simplicidad de gestionar el estado en el backend. Remix elimina la necesidad de un extenso código de gestión del estado de la interfaz de usuario y permite una experiencia de SPA completa. También admite enrutamiento anidado de la interfaz de usuario, proporcionando una forma conveniente de asociar componentes padre e hijo basados en segmentos de URL. Remix maneja la carga de datos y la gestión del estado automáticamente, simplificando el proceso de desarrollo y mejorando la experiencia del usuario. En general, Remix simplifica el modelo mental del desarrollo web y reduce la complejidad de gestionar el estado en aplicaciones de interfaz de usuario.

Pero en su mayor parte, el estado vivía en la base de datos. Así que cuando un usuario solicitaba una página, simplemente obtenían lo último de la base de datos. Y cuando hacen una publicación, actualizamos la base de datos y luego les enviamos un nuevo HTML basado en lo que está en la base de datos actualmente. Así que era realmente un modelo mental simple porque nunca te preocupabas realmente por el estado. Tal vez ponías algunas cosas en una cookie o algo así para administrar cosas en varias páginas que son locales para un usuario específico. Pero en su mayor parte, la gestión del estado era realmente simple.

Introducimos JavaScript en el lado del cliente y ahora tenemos que gestionar el estado en la interfaz de usuario, que es efectivamente solo una caché en el backend, y las cosas se complican mucho porque tenemos una barrera de E/S de red, que es nuestra red. Las cosas se vuelven realmente complicadas. Lo que Remix ha logrado hacer es darnos el modelo mental de lo antiguo donde no pensamos en el estado y las capacidades de lo nuevo donde tenemos, nos gustan las transiciones de página, la gestión del enfoque para la accesibilidad, mensajes de error animados, manejo de errores en el lado del cliente o mientras escriben, mostrar un mensaje de error. Todo eso se vuelve realmente, realmente difícil si quieres combinar algo renderizado en el servidor con algunos toques de JavaScript. Remix logra que se sienta como si no fueran solo toques de JavaScript. Es una experiencia de SPA completa, pero también nos brinda el mismo modelo mental de los viejos tiempos.

Como ejemplo rápido de esto, alrededor del momento en que desechamos la mejora progresiva como un mundo del software y dijimos, oh, cuando estás construyendo una aplicación realmente complicada, tienes que poner toda la aplicación en JavaScript, creamos esta cosa llamada TodoMVC. TodoMVC era solo para comparar todas estas diferentes bibliotecas de interfaz de usuario en una sola aplicación para facilitar las cosas. Así que tienes esta aplicación donde puedo escribir lo que sea, puedo marcar estas cosas y todo eso, y todo se almacena en el almacenamiento local. Así que recientemente hice una versión remezclada de esto, y ahora, en realidad, ¿tengo una contraseña para esto? No puedo recordar, espera un segundo. Sí, intenta adivinar esa contraseña. Es extremadamente larga. Aquí vamos. Genial, así que implementé esto. Ah, y por cierto, tiene autenticación de usuario. Y tiene persistencia real en una base de datos. Y así puedo iniciar sesión en esto en cualquier dispositivo y tener todas las mismas tareas pendientes. No es algo que hiciera TodoMVC. Además, es accesible mediante el teclado. También es algo que TodoMVC no era. Entonces, sí, implementé esto, y lo que es realmente, realmente genial de esto es que puedo demostrarte que al construir una aplicación web con Remix, no tienes que pensar en un estado de interfaz de usuario. ¿Quieres saber cómo puedo demostrártelo? Sin siquiera mostrarte el código, ni siquiera tengo que mostrarte el código. Así es como lo demuestro. Digo que JavaScript está desactivado. Y así, no hay JavaScript en la página. Si estuviera gestionando mi estado en la interfaz de usuario, entonces no podría hacer esto y hacer que funcione, pero totalmente funciona. Por lo tanto, no hay código en mi aplicación para esta implementación de esta aplicación que gestione un estado de interfaz de usuario. Así que, imagina en tu mente todo el código que escribes en tu interfaz de usuario que gestiona el estado. Probablemente sea como el 30 al 50% de tu código que escribes es sobre el estado. Tienes tu Redux o tienes tu MobX o tienes cualquier otra biblioteca de estado, si estás usando el contexto tú mismo, lo que sea que estés haciendo. Probablemente la mitad del código que escribes se dedica a gestionar el estado. Remix hace que no tengas que hacerlo. Y, por supuesto, los usuarios no desactivan JavaScript en su navegador, pero esto es solo cómo te demuestro que no necesitas gestionar el estado en una aplicación de Remix porque Remix lo gestiona por ti. Así que cuando habilito JavaScript, todo funciona y funciona mejor porque no tenemos que hacer actualizaciones completas de página. Pero nuevamente, no tuve que cambiar mi código de ninguna manera. Remix se encarga de todas esas cosas por mí y funciona muy bien. De hecho, esta aplicación es realmente increíble porque incluso si estoy en una red muy lenta, puedo marcar estas cosas y parece que se marcan al instante. Hay mucho más en esto y tengo una charla donde profundizo mucho más en esto, pero esto se llama UI Optimista y es increíblemente impresionante. Es súper, súper genial, donde aunque la solicitud realmente tarda dos segundos porque estoy en una red 3G lenta simulada, la interfaz de usuario se actualiza al instante y Remix hace que hacer ese tipo de cosas sea realmente, realmente fácil. Es extremadamente resistente a las malas condiciones de red. Esa es una de las partes más geniales de Remix, que simplifica tu modelo mental. Puedes desechar todo el código que tienes para gestionar el estado cuando estás construyendo aplicaciones de Remix. Eso es realmente genial. Además de eso, admitimos el enrutamiento anidado de la interfaz de usuario, y así como creo que Ling estaba hablando antes o no, no creo que fuera Ling. Fue alguien más, no puedo recordar. Alguien estaba hablando antes, tenemos React Router V6 y así tenemos estos componentes de salida de los que estábamos hablando y así para cualquier interfaz de usuario dada, tienes esta relación entre padres e hijos que están asociados a diferentes segmentos de la URL. Y así para nosotros, teníamos /publicaciones y así creamos ese directorio /publicaciones y ese módulo y mostré cómo el archivo padre post.tsx podría tener algún envoltorio alrededor y luego renderizaría un outlet. Y así es como funciona esa asociación a través de esa convención y a través del componente outlet. Entonces, el padre dice, aquí está toda la interfaz de usuario que quiero y si tengo algún hijo, aquí es donde van y esto tiene enormes implicaciones en tu experiencia de desarrollo mientras desarrollas tu aplicación, así como en la experiencia del usuario mientras cargamos datos y cosas cuando estás trabajando en esta parte de la interfaz de usuario que es solo un archivo único que dice, aquí está la interfaz de usuario que renderizo y aquí están los datos que necesito para hacer eso. Y sí, de hecho, sabes qué, he implementado esta aplicación y podemos ver específicamente esa ruta si vamos a ventas, facturas, ID de factura. Y así tiene el cargador para cargar los detalles de la factura. Todo esto es literalmente todos los datos que eso... En realidad, implementé más porque también tengo depósitos y cosas así, pero tiene todos estos datos que necesita la interfaz de usuario. Todo está justo aquí ejecutándose solo en el servidor, por el servidor. Así que puedes comunicarte directamente con tu base de datos y cosas así. Eso es lo que hace esta función get invoice details. Y luego la interfaz de usuario aquí abajo simplemente dice, ey, obtén mis datos para lo que necesito renderizar y lo renderizará en JSX. Y así no te preocupas por cómo se ven tus estados de carga en esta parte del mundo ahora. Por supuesto, a veces la carga llevará algún tiempo porque tienes una red y a veces es lenta. Y así tenemos API realmente geniales para los estados pendientes. Pero simplifica drásticamente esto porque no te preocupas por mantener estos datos actualizados. Remix mantendrá estos datos actualizados automáticamente para ti, manejando todo el abismo de la red por ti. Y no hay nada aquí que diga, oh, bueno, mi ruta principal necesita estos datos, así que también voy a cargar un montón de datos de mi ruta principal. Esto es literalmente lo que esta subruta necesita para renderizar lo que va a renderizar y todo lo demás es gestionado por sus padres.

4. Enrutamiento Anidado y Renderizado de Datos

Short description:

El componente padre es responsable de renderizar sus datos, como los elementos de la lista de facturas, el monto vencido y el monto próximo a vencer. La ruta de ventas y la ruta de diseño principal manejan la renderización de enlaces y el outlet. Con Remix, los equipos que trabajan en diferentes partes de una aplicación, como el encabezado y el pie de página, no necesitan comunicarse sobre el renderizado de datos. Al cargar los datos junto con el componente que se está renderizando, Remix proporciona una experiencia de usuario rápida sin estados de carga intermitentes. Esto elimina la necesidad de excesivos indicadores de carga y mejora la experiencia general del usuario.

Entonces, el componente padre para este caso será invoices.tsx y renderiza todo lo que desea, además del outlet, vamos a encontrar eso, sí, justo aquí. Ahí está el outlet. Supongo que aquí estará la lista de facturas. Así que el padre solo es responsable de sus datos. Aquí está eso mismo. El padre solo necesita los elementos de la lista de facturas, el monto vencido y el monto próximo a vencer. Así que aquí podemos ver eso mismo aquí. El monto vencido, el monto próximo a vencer y la lista. Y luego, en el lado derecho de la lista, simplemente renderizamos donde está nuestro hijo. Lo mismo ocurre con la ruta de ventas. Entonces, si vamos a sales.tsx, esta es la ruta principal aquí. Es responsable de renderizar todos estos enlaces y luego renderiza el outlet y eso es todo. Simplemente renderiza los enlaces y luego el outlet. Y luego, la ruta de diseño principal aquí es apt.tsx y está renderizando todos los NavLinks a la izquierda. En realidad, tenemos nuestro indicador de carga si alguna vez hay una transición en curso. Noté que Stefan está aquí y Stefan en realidad escribió esta biblioteca, Spindlay. Así que un saludo para ti, Stefan, esa biblioteca es increíble. Y renderizamos nuestro outlet justo aquí. Entonces, la ruta de diseño para nuestra aplicación es responsable de este Nav izquierdo y luego renderiza el outlet y dice, si tengo algún hijo, aquí es donde van. Esto es increíble. Así que imagina que estás en una empresa y tienes como tres equipos trabajando en una aplicación o incluso solo dos ingenieros trabajando en una aplicación, escala desde aplicaciones pequeñas hasta aplicaciones realmente grandes. Y así, uno de esos equipos será responsable del diseño general de tu sitio. Hacen el encabezado y hacen el pie de página y luego no les importa nada más. Sin enrutamiento de diseño de interfaz de usuario, esos equipos tienen que comunicarse sobre los datos que necesitan renderizar. Porque si cada página en esa aplicación necesita renderizar el encabezado y el pie de página y tienes un equipo responsable de eso. Cada vez que ese equipo necesita actualizar el encabezado y el pie de página, necesitan comunicarse con todos los equipos y decir, hey, necesitas pasarme estos props adicionales o lo que sea. Y así, lo que suele suceder es que decimos, carguemos los datos que necesitamos en el cliente y de esa manera no tenemos que comunicarnos con nadie. Simplemente lo cargaremos junto al componente que estamos renderizando y así no tienen que pasarnos ningún prop. Esto conduce a una mala experiencia de usuario porque terminas con este tipo de estado de carga intermitente en lugar de, en realidad tengo libros falsos aquí. Y si inicio sesión y vamos a la página de ventas, vamos a ir a facturas. Sí, todos mis clientes están atrasados, están en problemas. Pero si voy a esta página, como verás, se renderiza al instante y eso es exactamente lo que estamos demostrando aquí, se renderiza al instante. Se ve increíble. En lugar de tener esta experiencia intermitente que tenemos en todas partes. Mira esto, voy a chase.com y tenemos un montón de indicadores de carga por todas partes. ¿Qué es esta basura caliente? Sin ofender a chase.com porque casi todos los sitios están haciendo esto. Twitter.com. Tenemos cosas rebotando, oh, en realidad oculto esto porque no me gustan estas imágenes, pero a veces tienen cosas realmente estúpidas sucediendo aquí. Pero tienes indicadores de carga por todas partes, en toda la web. ¿Por qué estamos haciendo esto a nuestros usuarios? Hay una razón, hay una buena razón y no tenemos que hacerlo más porque existe Remix. Entonces sí, en lugar de tener la experiencia intermitente a la izquierda, podemos tener esta experiencia rápida a la derecha, brindar a nuestros usuarios una experiencia de usuario mucho mejor y podemos tener una experiencia de desarrollo increíble porque el equipo responsable del encabezado y el pie de página solo puede ser responsable de esas cosas y no les importa el hijo y al hijo no le importa el padre. Esto es, tal vez esa metáfora no es buena porque los padres deberían preocuparse por sus hijos y los hijos deberían preocuparse por sus padres. Pero en el mundo del enrutamiento anidado, no tienen que preocuparse y creo que eso es increíble.

5. Capacidades de Remix y Gestión de Datos

Short description:

Remix puede hacer muchas cosas increíbles. Maneja el empaquetado, la compilación y la obtención de datos. Precarga datos según la navegación del usuario, lo que lo hace rápido. Las mutaciones de datos son simples con un formulario y una acción en el mismo archivo. Remix gestiona los datos, el reenvío de formularios, las condiciones de carrera y los estados de error.

De acuerdo, también nos gusta, hay muchas cosas realmente increíbles que Remix puede hacer porque es tu empaquetador y compilador y tu biblioteca de obtención de datos, como la precarga de datos según a dónde va a ir el usuario, por lo que la navegación es realmente, realmente rápida. Y luego, las mutaciones de datos son realmente buenas y también lo veremos, básicamente es solo este formulario, eso es todo. Tienes un formulario y luego en el servidor tienes esta acción y esas dos cosas están literalmente en el mismo archivo. Así que aquí en el ID de la factura, tenemos esta acción que se puede llamar cuando queremos crear un depósito en una factura. Y esto solo se ejecuta en el servidor y tu formulario asociado está justo aquí y es increíble, es tan, tan, tan genial. Entraremos en eso un poco más tarde, pero Remix se encarga de mantener tus datos actualizados, gestiona el reenvío de formularios, gestiona las condiciones de carrera, todas las cosas que normalmente pasamos por alto cuando construimos esto nosotros mismos porque estamos demasiado ocupados tratando de enviar las cosas en primer lugar. Y Remix se ha encargado de todo eso por ti. También se manejan los estados de error y es increíble, pero no tenemos tiempo para profundizar demasiado en eso.

QnA

Escalabilidad, WebSockets y Compartir Datos en Remix

Short description:

Mi equipo está utilizando actualmente Next.js y estamos discutiendo cómo renderizar y evitar costos del servidor. Remix puede lograr características de rendimiento similares a SSG configurando un CDN y utilizando encabezados de caché. También proporciona palancas para manejar diferentes casos de uso y necesidades. Remix admite WebSockets y eventos en el lado del servidor, lo que lo hace adecuado para escenarios multiusuario en tiempo real. El número de puerto corresponde al ejercicio y se pueden compartir datos entre rutas utilizando el gancho use matches.

Tengo una pregunta sobre la escalabilidad y el servidor, me preguntaba, mi equipo está trabajando en un proyecto con Next.js en este momento y estamos teniendo grandes discusiones sobre cómo renderizar para evitar costos del servidor, y así sucesivamente. ¿Cómo escala Remix en esta situación? ¿Cómo se desempeña?

Sí, esa es una excelente pregunta. Entonces, en un escenario de Next, probablemente estén pensando, bueno, hagamos SSG en esto para no tener que acceder a nuestro servidor. Lo interesante de ese enfoque es que, a menos que todo en la página sea completamente estático, lo cual supongo que no es el caso, como que tendrán indicadores de carga para obtener data, aún estarán accediendo a sus servidores. Y así obtendrán esos datos. Ahora, tal vez estén utilizando un tercero, por lo que en realidad no están accediendo a sus servidores, están accediendo a los de otra persona. Y en ese caso, sí, obtendrán un beneficio. Pero diría que Remix también puede hacer lo mismo. No admitimos SSG, pero SSG es simplemente una implementación personalizada de un CDN con encabezados de caché. Y si quisieran tener eso, la misma idea que SSG utilizando Remix, que no admite SSG, simplemente configurarían un CDN como Cloudflare, o Fastly o cualquier otro. Configurarían eso, y luego harían que su servidor envíe encabezados de caché con directivas en su encabezado de caché. Y luego, la próxima vez que alguien visite el CDN, el CDN dirá: `Oh, eso está en caché, déjame enviar la versión en caché`. Por lo tanto, no accederá a su servidor. Por lo tanto, obtendrán las mismas características de rendimiento con SSG sin tener que hacer SSG. El beneficio realmente bueno de esto es que si comienzan con SSG desde el principio y luego deciden más adelante, `Oh, necesitamos algo más, como queremos renderizar esto en el servidor`. Tendrían que reestructurar completamente su solución. Si comienzan con el renderizado en el servidor y solo usan encabezados de caché, y luego se dan cuenta de que necesitan renderizar más en el servidor. No pueden simplemente tenerlo en una caché compartida. Entonces, simplemente desactivan los encabezados de caché y listo, ahora están renderizando en el servidor. Pero en cuanto a la escalabilidad, si eso es una preocupación, simplemente usen encabezados de caché. Y sí, tengan en cuenta que no están resolviendo problemas de escalabilidad si tienen que hacer solicitudes de red para obtener datos de usuario, porque, en ese caso, aún están accediendo a su servidor. Así que sugiero usar encabezados de caché. Y si, por ejemplo, no quieren tener muchos indicadores de carga por todas partes, entonces sugiero hacer caché en el servidor con algo como Redis. Y sí, lo realmente genial de Remix es que en lugar de ofrecerte muchos enfoques diferentes para un problema, te ofrecemos palancas para un problema, para manejar diferentes casos de uso y necesidades. Entonces, en lugar de tener que tomar este enfoque para este caso de uso y este enfoque para este otro caso de uso, en realidad solo tomas un enfoque único y luego usas la palanca para cambiar en una base por ruta los tipos de cosas que necesitas. Y de hecho, Ryan dio una charla realmente genial recientemente en Reactathon, Reactathon, vean los videos. Veamos, sí, ahí está. Déjame copiar esa URL, y la pegaré en Discord para que alguien la agregue a las notas si quieren. Pero allí habla un poco sobre esas palancas y algunas de las cosas realmente, realmente geniales que vendrán muy pronto también.

Tengo una pregunta, ya que también estamos en el tema de Ryan Florence. Creo que vi un tweet suyo hace un tiempo en el que hablaba sobre cómo maneja Remix los WebSockets y cómo a menudo esa es una especie de pregunta sobre si maneja escenarios multiusuario en tiempo real. Y la respuesta que propone es como eventos de servicio y eventos de servidor, lo cual me parece muy interesante y convincente cuando la comunicación en tiempo real que deseas tener implica un envío de formulario, pero yo trabajo en un equipo donde estamos construyendo una aplicación que es, supongo, tan en tiempo real como algo como Figma, donde quieres poder ver las posiciones del mouse de otros usuarios o que realicen acciones que no involucren el envío de formularios y luego propagar ese estado a través de la aplicación a varios clientes. ¿Es algo que la capa de red de Remix está considerando resolver o es una pregunta demasiado profunda y específica para ahora mismo?

No, no, no, esa es una excelente pregunta. En primer lugar, diré que Remix admite WebSockets tan bien como cualquier otro marco que puedas usar, así que no hay nada más adecuado para WebSockets que yo sepa. Entonces, si esa es la elección tecnológica que quieres hacer, está perfectamente bien. Pero no creo que los eventos en el lado del servidor requieran un envío de formulario. Por lo tanto, puedes configurar una solicitud de evento en el lado del servidor sin tener que enviar un formulario en absoluto. Por lo tanto, podrías hacer totalmente Figma, posición del mouse, todas esas cosas con eventos en el lado del servidor. Y la ventaja de usar eventos en el lado del servidor es que es solo una solicitud, por lo que hay muchas cosas realmente geniales que vienen con eso. Y está soportado de inmediato con Remix. Puedes tener una ruta de recurso que envíe una respuesta que establezca ese flujo de eventos. Y sí, puedes construir totalmente ese tipo de interfaz de usuario con eventos en el lado del servidor. Y creo que es una tecnología subutilizada porque tenemos WebSockets y pensamos, okay, esto es genial. Y realmente lo es. Aunque es difícil de escalar, por eso tenemos cosas como Pusher. Pero sí, diría que tal vez vuelvan a considerar los eventos en el lado del servidor si lo desean, pero si están contentos con WebSockets, eso también es genial. No sé, tal vez eventualmente tengamos algo, algún soporte incorporado para WebSockets, pero estamos más interesados en pensar en casos de uso. Y creo que el caso de uso que describiste está bastante bien soportado por eventos en el lado del servidor. Pero no tengo mucho tiempo para profundizar más en eso ahora.

Así que ten en cuenta que el número de puerto, ups, esta es la aplicación equivocada. El número de puerto al que debes prestar atención cuando estás viendo la aplicación debe corresponder al ejercicio en el que estamos. Entonces, estamos en el 4001, es el ejercicio uno. Ahora quieres pasar al ejercicio dos, por lo que ahora el número de puerto debe ser 4002. Ahí es donde deberías estar. Tenemos el enlace al artículo del blog, obtenemos la publicación justo aquí. Y para el ejercicio dos, estamos en la carga de data. Si vas al archivo Léeme, te mostrará que debes comenzar con la carga de data y detenerte cuando llegues a obtener datos de una fuente que apareció en mi otro navegador. Sí, detente aquí cuando termines con la sección de carga de data aquí. Así que tenía un par de preguntas que responderé rápidamente aquí y luego podemos pasar a hacer realmente esta parte del ejercicio. Entonces, Felix en el chat de Zoom preguntó, ¿cómo se comparten los data entre rutas? Si necesitas compartir data entre rutas, tenemos esta cosa llamada use matches que te permite compartir ese data o acceder a data en otras rutas. Cuando hablas de compartir entre rutas, es como de padre a hijo o de hijo a padre. Entonces, si el padre necesita acceder a algo que el hijo tiene, como para una interfaz de migas de pan o algo así, eso es para lo que se usa matches. Si el hijo necesita algo que el padre tiene, también se usa matches. Y en realidad hacemos eso como parte integrada del stack Indy en nuestros utilitarios aquí para obtener el usuario. Entonces, tenemos este gancho use matches data que escribí que básicamente usa los matches, encuentra las rutas por el ID de la ruta. En este caso, el usuario está en la ruta de la ruta y simplemente obtenemos el data de la ruta de la ruta. Y luego obtenemos el usuario de eso. Y sí, puedes compartir eso hacia arriba y hacia abajo de la cadena y es bastante sencillo. A menudo no te encontrarás teniendo que hacer esto para más que solo datos de usuario pero a veces sí. Y por eso tenemos soporte para eso en primer lugar. Así que sí, espero que eso responda esa pregunta.

Almacenamiento de Datos y Función de Carga

Short description:

Remix simplifica la gestión de datos para la interfaz de usuario, pero el almacenamiento está fuera de su alcance. Puedes usar Remix para obtener datos de un servidor utilizando un cargador. Remix también puede manejar rutas de recursos para APIs REST o GraphQL. Construir una aplicación web y móvil en Remix con co-ubicación es una posibilidad. La función de carga se ejecuta en el servidor, lo que permite operaciones seguras y bibliotecas pesadas. Los registros de la consola en el cargador solo se muestran en la terminal, mientras que los registros en el componente aparecen tanto en la terminal como en el navegador.

Y creo que eso fue todo allí. También hubo una pregunta sobre dónde se almacenan los data. Entonces, en nuestra aplicación, estamos usando Postgres o SQLite, pero sí, el almacenamiento de data está fuera del alcance de donde está actualmente Remix. Tal vez algún día tengamos un ORM incorporado y una base de datos incorporada o algo así, pero eso es bastante improbable. Tus data pueden estar en un tercero o pueden estar en tu propia base de datos o donde quieras que estén. Pero sí, Remix simplemente facilita mucho obtener data para tu interfaz de usuario.

¿Es Remix la herramienta adecuada para un widget? No usarías Remix para el widget en sí porque Remix se trata de toda la aplicación y el enrutamiento y cosas así. Un widget realmente no hace nada de eso. Pero sí, puedes totalmente, creo que Nick respondió esto. Puedes publicar un componente de React, usarlo en cualquier lugar. Probablemente eso es lo que haría. Sí, creo que eso es bastante, oh sí, en cuanto a cómo Remix obtiene data del servidor. Entonces, hay un esquema de URL especial que es un detalle de implementación que no deberías utilizar tú mismo para hacer estas solicitudes para obtener este data. Así que tenemos este cargador. Remix realiza una solicitud de búsqueda especial para obtener ese data durante las transiciones del cliente. Pero puedes crear lo que llamamos rutas de recursos, que son rutas que no tienen una exportación predeterminada. Si no tiene una exportación predeterminada y luego es una ruta de recurso, puedes acceder directamente a esa URL. Y así puedes tomar tu API REST o tu API GraphQL, construirlo en Remix como rutas de recursos, y luego tu aplicación móvil podría usar eso. Y de hecho, estamos pensando que debería ser posible en el futuro construir una aplicación web y móvil, como una aplicación React Native, en Remix y tener esta co-ubicación al igual que lo hacemos para el lado web. Creo que eso debería ser posible y eso sería bastante legítimo. No estamos trabajando activamente en eso, pero es algo en lo que hemos pensado.

De acuerdo. Sí, una pregunta sobre por qué los registros de la consola dentro del cargador solo se muestran en la terminal, mientras que en el componente, se muestran tanto en la terminal como en la interfaz de usuario o el navegador. La razón es que tu función de carga y eso carga data solo se ejecuta en el servidor. Esto es genial porque significa que puedes usar claves privadas. Puedes comunicarte con una base de datos. Puedes hacer todas las cosas que son realmente molestas. Puedes usar bibliotecas pesadas y no tener que enviarlas al navegador. Todas las cosas que puedes hacer en este cargador. Y luego Remix es el que se asegura de que podamos ir entre el cargador y el navegador y obtener ese data a través de ese abismo de red. Y por eso ves los registros de la consola aquí solo se muestran en la terminal porque eso es todo lo que se está ejecutando. Para tu componente, ves el registro de la consola en la terminal porque se está ejecutando en el servidor para la representación del servidor. Y luego lo ves en el navegador porque se está hidratando. Eso es lo que está sucediendo allí.

Carga de Datos y Manejo de Respuestas

Short description:

Vamos a manejar la carga de datos para nuestras publicaciones. Utilizaremos una función especial llamada json de Remix Run node para crear una nueva respuesta en formato json o json-stringified, con encabezados de aplicación json y estado 200. Esta función simplifica el proceso de creación de una respuesta json. Remix normaliza la respuesta de la solicitud en cualquier plataforma a la API de Fetch web, lo que te permite trabajar con la plataforma web sin preocuparte por los detalles de implementación.

Genial, excelente. Así que vamos a trabajar en esto. Tenemos, cierra todas estas cosas y vuelve aquí a nuestro readme. Así estamos todos en la misma página. Esa es una ventana de navegador diferente. Ahí vamos.

De acuerdo, vamos a manejar la carga de data. Necesitamos un cargador para nuestras publicaciones porque vamos a tener un montón de publicaciones aquí. Así que voy a copiar esto y llevarlo a nuestro índice de publicaciones para que podamos listar un índice de todas nuestras publicaciones. Permíteme deshacerme de esa terminal.

Este json es una función especial que vamos a obtener de Remix Run node. Y en realidad no es tan especial. En realidad, lo que hace es crear una nueva respuesta que es json o json-stringified y tiene encabezados de aplicación json. Eso es básicamente todo, ah, y también estado 200. No 2000, solo 200. Esto está dando un error porque, ah, cierto. Esto debe ser, ah, tipo de contenido. Ahí vamos. Eso es todo lo que hace el json. Es útil y no quiero tener que escribir eso cada vez, básicamente siempre estás usando json en tu cargador y por eso tenemos la función pero eso es todo lo que hace. Crea una nueva respuesta. Ahora, como mencioné, esto solo se ejecuta en el lado del servidor y en entornos donde el servidor no admite la solicitud de respuesta, Remix convierte la solicitud en lo que sea para tu cosa serverless o tu cosa Express o lo que estés usando, lo convierte en una solicitud Web Fetch y lo rellena en esos entornos donde no se admite la solicitud Web Fetch y luego la respuesta que envías, la convierte en una respuesta Web Fetch en lo que sea que tu cosa serverless o tu Express o lo que sea necesite para su respuesta y eso es algo realmente genial de Remix es que normalizamos la solicitud y respuesta en cualquier plataforma en la que estés ejecutando a la API de Fetch web. Así que siempre estás trabajando con la plataforma web y no tienes que preocuparte por los detalles del objetivo de implementación al que estás apuntando.

Obtención y Renderizado de Datos

Short description:

Enviamos nuestro JSON con la publicación y accedemos a él utilizando el gancho de datos del cargador de uso. Las publicaciones se recuperan mediante la deconstrucción de los datos. El renderizado del servidor y la transición del lado del cliente funcionan perfectamente, con registros que aparecen en los entornos correspondientes. Durante una transición del lado del cliente, no hay registros en la terminal ya que el componente ya está hidratado en el lado del cliente.

Genial, entonces estamos enviando nuestro JSON con esta publicación y para acceder a ese JSON, vamos a decir usar cargador data, ups, usar cargador data, ahí vamos. Para obtener nuestras publicaciones, simplemente vamos a deconstruir eso y cl publicaciones. Genial, así que si hago un registro en la consola y vengo aquí y actualizo entonces vamos a ver nuestras publicaciones ahí mismo. Tenemos nuestras publicaciones, déjame aumentar eso un poco. Genial, todo eso vino del servidor. Esto, como se mencionó, si hacemos un registro en la consola aquí en el servidor y guardamos eso, si miramos aquí, en realidad vemos aquí en el servidor y luego vemos nuestras publicaciones, eso es para el renderizado del servidor. Y luego, si venimos aquí, solo vemos las publicaciones. Así que esa es una característica muy útil de Remix que maneja esa transición. Y también esto funciona totalmente para una transición del lado del cliente también. Así que hacemos el renderizado del servidor aquí y hacemos clic en este enlace. Todavía vamos a obtener ese registro que muestra las publicaciones, todavía vamos a obtener este registro. Pero notarás que no obtenemos... Oh aquí en realidad, hagamos esto. Renderizado del servidor de publicaciones. Hagamos eso. De acuerdo, así que si vengo aquí y ahora borramos todo eso. Así que hago una transición a la publicación del blog. Vemos, oh ja ja renderizado del servidor de publicaciones. Ese no era ese componente, eso está mal. Pero no verás el renderizado del servidor de publicaciones en la terminal porque esta es una transición del lado del cliente. Así que no necesitamos ejecutar la exportación predeterminada. Eso ya ha sido hidratado. Todo eso está ahora en el cliente así que no necesitamos volver a renderizar esto en el servidor o algo así. Así que no hay registros cuando haces esa transición del lado del cliente. Espero que eso tenga sentido.

Datos del Cargador y Uso de Datos del Cargador

Short description:

Definimos el JSON que debe regresar del cargador como una convención. Sin embargo, no se recomienda usar un genérico para el uso de datos del cargador. TypeScript no puede verificar que los datos recibidos coincidan con el genérico pasado. Esto es un problema específico de TypeScript. Estamos trabajando en mejorarlo en el futuro. Por ahora, es importante no engañarse sin saberlo. Remix se asegura de que los datos del cargador para una ruta se carguen antes de hacer la transición a esa página. No hay carga asíncrona ocurriendo en el momento de usar los datos del cargador. No necesitas preocuparte por un estado de carga en este caso. El cargador no es una palabra clave especial, pero es necesario para que funcione el uso de datos del cargador. Cuando el usuario hace una transición, Remix reconoce el cargador para esa ruta y realiza una solicitud de búsqueda. Remix maneja la solicitud de búsqueda y pasa la respuesta a la interfaz de usuario.

De acuerdo, genial, así que tenemos nuestra publicación. A partir de aquí, es solo tonterías de JSX así que no nos molestaremos con eso. Voy a copiar y pegar esto y pegarlo justo aquí. Vamos a traer el enlace de RemixRunReact. Guardar eso y ahora tenemos todas nuestras publicaciones listadas. Y luego hacemos algunas cosas de TypeScript. No creo que te importe aprender cómo escribir correctamente todo esto o al menos no necesitas que yo escriba las definiciones de tipos. Así que aquí hacemos que JSON sea un genérico donde puedes pasar los datos del cargador. ¿Qué? Bueno, esto es un error. Necesito hablar de esto, maldición. Si alguien quiere hacer una solicitud de extracción al tutorial por favor hazlo porque esto está mal. No debes usar el genérico aquí y te explicaré por qué en un momento. Pero sí, simplemente estamos definiendo, hey, este es el JSON que debe regresar de este cargador. Esto es solo una convención, no importa realmente si es de esta manera que lo haces. Podrías ponerlo en línea ahí o lo que sea. Podrías llamarlo como quieras. Pero yo lo llamo datos del cargador y es un array de publicaciones que tienen slug y título. Y luego en el lado del cliente o en la interfaz de usuario tenemos estos datos del cargador. Estamos usando este genérico para el uso de datos del cargador. No deberías hacer eso. Y la razón por la que no deberías hacerlo es porque esto es exactamente lo mismo que esto. Porque no hay forma para que el uso de datos del cargador sepa realmente que los datos que estás obteniendo son el genérico que pasaste. Así que esto no es algo específico de Remix. Es algo específico de TypeScript. Así que si, aquí tienes un consejo rápido. Entonces, si obtengo algo, y luego aquí está mi genérico, y luego retorno i como genérico, nunca hagas esto. Casi nunca hagas esto, a menos que sepas con certeza que esto es realmente la cosa que piensas que es. Porque ahora puedo decir que foo es igual a obtener algo como un número. Y ahora foo es, ¿es eso un número? Oh Dios mío, es un número. Pero en realidad no lo es, y no sé que me he mentido a mí mismo. Porque cuando haces un genérico que dice que aquí está la cosa que debe ser devuelta, piensas que la función está manejando eso de alguna manera. Pero en realidad lo que está haciendo es simplemente mentirte. Está diciendo lo que sea, lo que quiera decir. Entonces, por eso decidimos eliminar el, o degradar el genérico, porque te estás mintiendo a ti mismo. En realidad no tenemos forma de saber, con certeza, si hubo algo extraño que sucedió en la red para arruinar tus datos del cargador o agregar propiedades o quién sabe qué hizo. Y así, esa es simplemente la naturaleza de una cosa de red. Tenemos el mismo problema con un límite de E/S del sistema de archivos. Alguien guarda un archivo, y luego alguien lee el archivo. No puedes asumir que cuando lees el archivo, es la misma cosa que se guardó, porque algo más podría haber cambiado ese archivo entre esas dos cosas. Sí, adelante. Sin embargo, podrías pasar la función misma, como los datos del cargador, como un argumento a un tipo, y luego podrías deducir eso del tipo si- Sí, en realidad estamos trabajando en mejorar esto, y eventualmente podrás hacer esto. Sí, exactamente. Esa será eventualmente la forma en que hagamos esto. Exactamente, eso es lo que estaba- No puedes hacer esto hoy porque el cargador devuelve una respuesta, y no puedes deducir eso en este momento, pero sí, eventualmente eso será así, y será mucho mejor, pero por ahora, no te mientas a ti mismo sin saberlo. Deberías mentirte a ti mismo sabiéndolo. ¿Tiene sentido? Si vas a mentirte a ti mismo, al menos debes saberlo. De todos modos, desearía haber actualizado el tutorial del blog para no tener que pasar los últimos cinco minutos explicando por qué estaba mal. Así que ahí lo tienes. Y si no tuvo sentido o si te perdiste en todo eso, no te preocupes porque de todos modos estaba mal. Así que estamos bien. De acuerdo, eso es todo para la carga de datos. ¿Alguna pregunta sobre la carga de datos en Remix? Vamos a tomar un descanso después de esto, así que si tu cerebro comienza a sentirse frito, no te preocupes, un descanso vendrá a salvarte. Entonces- Solo me pregunto si el uso de datos del cargador está utilizando automáticamente la función del cargador, ¿verdad? Sí, así es como funciona. Remix no hará la transición a esta página hasta que los datos del cargador para esta ruta se hayan cargado. Y así cuando decimos uso de datos del cargador, Remix ya tiene los datos. Y simplemente encuentra los datos para la ruta que los está solicitando y te los pasará. Y así no hay nada asíncrono sucediendo en este punto. Toda la asincronía ha ocurrido antes de llegar aquí. Y por eso no necesitas preocuparte por un estado de carga aquí mismo. Ahora, tenemos APIs para estados de carga porque a veces la red es lenta, pero no tienes que preocuparte por eso aquí. ¿Alguna otra pregunta? Hola. ¿El cargador es una palabra clave especial que tenemos que usar para que funcione el gancho de uso de datos del cargador? Lo siento, no entiendo tu pregunta. ¿Podrías repetirla? Entonces las variables del cargador unifican sobre. ¿Es una palabra clave especial que tenemos que usar para que funcione el gancho de uso de datos del cargador? Pero de todos modos no es importante. Así que exportamos el cargador. Y Remix lo va a, Remix sabrá, oh, hay un cargador para esto. Y así cuando el usuario hace una transición, dirá, oh, hay un cargador para esa ruta. Permíteme hacer una solicitud de búsqueda. Y luego cuando se hace esa solicitud de búsqueda, Remix es quien la maneja. Y dice, oh, quieres llamar a este cargador. Permíteme llamar a ese cargador, obtener la respuesta, enviar la respuesta a la interfaz de usuario.

Datos del Cargador y Gestión del Estado

Short description:

Remix ofrece flexibilidad en el acceso a los datos del cargador y permite múltiples instancias de datos del cargador en un componente. El gancho useFetcher se puede utilizar para cargar datos solo en el cliente. No se puede acceder a los datos del cargador padre en el cargador del hijo, pero se pueden acceder en el componente. En futuras versiones de Remix, es posible que se introduzca una API para acceder a los datos del cargador padre. La gestión del estado en Remix abarca todo y es más fácil de usar que Redux. Sin embargo, la gestión del estado en Remix se centra en el estado persistente, por lo que el estado local de la interfaz de usuario que no se persiste no será gestionado por Remix.

Y luego, cuando eso esté hecho, Remix toma esa respuesta, la guarda en sus datos y cuando se renderiza, dice: 'oh, quieres los datos, aquí los tienes'. Así que si cambio el nombre a otra cosa, como cargador uno, ¿seguirá funcionando? No, no lo hará. Esto es una convención. Tiene que ser cargador. Tiene que ser cargador. Sí, básicamente ocurre en el backend de alguna manera. Lo siento, ¿qué dijiste? Entonces, es como Remix, solo detecta la palabra clave cargador, en este caso. Podrías tener un nombre diferente para eso. Correcto. ¿Y puedes tener dos vistas de datos de cargador en un componente o solo una? Sí, podrías usarlo dos veces y sería el mismo dato. Y el beneficio de eso sería que si tengo un subcomponente y necesito los datos del cargador, puedes obtenerlos allí y no tener que pasar props por todos lados. Así que sí, hay situaciones en las que haces eso. ¿Puedo tener dos cargadores diferentes o puedo tener un bucle para poder, si tengo una solicitud de recursos de dos cosas diferentes, entonces necesito hacerlo en un solo cargador o puedo tener dos cargadores diferentes? Hay diferentes casos de uso de los que estamos hablando aquí, pero el más obvio sería, aquí está mi primera cosa y la segunda cosa es esperar, Promise.all, y luego obtener la primera cosa y obtener la segunda cosa. Y así ahora tienes ambas cosas, las envías de vuelta. Pero si una es realmente lenta y no quieres que la página espere, preferirías enviar un spinner de carga, tenemos una API realmente increíble para eso que llegará pronto llamada API Diferida, te va a sorprender. Pero incluso hoy, si eso es lo que quieres, podrías usar un gancho llamado useFetcher y cargarlo solo en el cliente. Sí, eso es posible hoy, pero tenemos algo aún mejor que viene, que es un poco más profundo que un taller de Fundamentos de Remix. Así que eso es todo lo que voy a decir al respecto. Gracias. Sí, tengo una pequeña pregunta tal vez, si aún tienes tiempo. Sí, y luego Ling, veo que tienes la mano levantada también. Sí, que hable Ling primero, no levanté la mano. Está bien, no hay problema. Gracias. Entonces, probablemente solo una pregunta muy pequeña. ¿Hay otras funciones de API disponibles además del cargador, verdad? Sí, sí, te refieres a otras exportaciones en este módulo? Sí, las hay. Si vas a convenciones y luego vas a la API del módulo de ruta, las tienes todas aquí. ¿Puedes...? Pegaré eso en Zoom. Gracias. Y en Discord. De acuerdo, adelante. ¿Es Gunther? Sí. Sí, di eso, por ejemplo, tienes una URL con dos IDs y tienes el cargador hijo. ¿Puedes acceder al ID del padre? Sí, por ejemplo, obtienes este objeto params y eso dirá, como slug, y luego puedes obtener, por ejemplo, el ID del padre. Entonces, si estamos vendiendo autos o algo así y decimos params.make y params.model. Así que tienes slash slash make slash model, puedes acceder a todos ellos. ¿Y puedes acceder a los datos del cargador del padre? No, no puedes. La razón de eso es que cuando tienes múltiples rutas, queremos ejecutar todas ellas en paralelo. No queremos ejecutar una después de la otra. De lo contrario, sería muy lento. Y así, no puedes acceder a los datos del cargador padre en el cargador del hijo. Puedes hacerlo en el componente, simplemente no en el cargador, porque los ejecutamos todos en paralelo. Y además. Entonces, tienes que volver a obtenerlo, básicamente, si necesitas los datos del padre. Sí. De acuerdo, perfecto. Ten en cuenta que esto se ejecuta en el servidor. Y así que si tienes que acceder a la base de datos para obtener el modelo y los padres, y luego accedes a la base de datos para obtener el modelo en el cargador o en el hijo, eso se ejecuta en el servidor. Así que eso está bien. Pero si no lo está, podrías implementar una capa de caché en tu servidor para decir, oh, ya estoy solicitando esto, espera mientras lo obtengo para el otro. Eso no es ridículamente complicado. Pero también vamos a crear eventualmente esta API especial que probablemente se verá así antes del cargador. Y esto será algo que simplemente devuelve algunos datos que deseas tener. Y esto se ejecutará antes de que se ejecuten los cargadores. Así que realmente no quieres usar esto porque automáticamente hace que todos tus cargadores tarden tanto como esto antes de que comiencen a ejecutarse. Y así, esto solo es para esas cosas que son realmente críticas para todos los hijos. Pero sí, probablemente habrá una API como esa en el futuro. Perfecto, ¿y cómo obtienes los datos del cargador del padre con los datos del cargador? ¿O eso no es parte de esto? Sí, si quieres acceder a los datos del cargador del padre, puedes usar matches, esto te dará todas las rutas coincidentes y los datos del cargador padre estarán allí. ¿Hay algo relacionado con la gestión del estado que solo funcione utilizando el enfoque de Redux o Remix lo cubre todo? No hay literalmente nada que puedas hacer con Redux que no puedas hacer con Remix, y Remix lo hace más fácil. La única cosa que, como advertencia, es que la gestión del estado en Remix se trata de estado persistente. Entonces, si tienes un estado de la interfaz de usuario que solo aparece en la interfaz de usuario y al actualizar desaparece, cosas como si un modal está abierto o si se selecciona un elemento del menú, algo así. Entonces, sí, esas cosas no serán gestionadas por Remix, pero la mayoría de esas cosas son cosas a nivel de componente, por lo que no usarías Redux para eso o no deberías. Es una forma realmente excelente de hacer una aplicación de React muy lenta. Pero sí, todas esas son solo cosas de estado local. A veces hay cosas en las que piensas, necesito compartir esto en toda la aplicación y no se persiste, así que no lo pondré en Remix. Sí, no hay muchas situaciones como esa, pero seguro que hay algunas.

Usando Remix y Parámetros Dinámicos

Short description:

La última versión de React router admite el uso de Remix. Redux aún puede ser útil para aplicaciones altamente personalizables. El método JSON en el cargador tiene implicaciones al convertir objetos en cadenas. Es importante probar las aplicaciones de Remix, y las pilas vienen preconfiguradas con herramientas de prueba. La aplicación de controles de estructura o validación de esquemas a los cargadores no está permitida debido al proceso de compilación. Los parámetros dinámicos en las rutas de Remix son fáciles de implementar.

Y aún puedes usar Remix para eso porque la última versión de React router lo admite hey, ¿dónde está mi... Oh, cierto, me deshice de eso. Vamos a las notas. Entonces, la última versión de React router tiene esta característica en el outlet llamada contexto. Y así puedes poner cualquier valor que quieras allí y luego el hijo aquí puede decir, ¿dónde está mi, sí. Puede usar el contexto del outlet para obtener lo que se pasó en el contexto padre. Y así, si quieres hacer algún estado de la interfaz de usuario que se comparte en las rutas y cosas así, entonces ni siquiera tienes que crear tu propio proveedor de contexto, puedes usar la API de contexto de outlet. Pero si no quieres hacer eso, como si quisieras crear tu propio proveedor de contexto, eso también está totalmente bien. No puedo imaginarlo. Así que en realidad hay una situación en la que Redux aún podría ser útil, en mi opinión, y es si estás construyendo una aplicación que es muy personalizable, como otras, como tus usuarios pueden escribir sus propios complementos para tu aplicación, y necesitan poder conectarse cuando suceden diferentes cosas. Estoy pensando en cosas como Hyperterm donde puedes tener complementos y cuando se envía alguna acción, el complemento quiere poder hacer algo o lo que sea. Eso parece ser un caso de uso razonable para algo como Redux, pero eso es como el 0.00001% de los casos de uso. Así que realmente no veo muchas situaciones donde Redux sea muy útil.

pepf, así que el método JSON en el cargador tiene algunas implicaciones, nada nuevo, todo son estándares web, eso es bueno saberlo. Stringifies, sí, convierte en cadena los objetos y objetos de JavaScript como fecha y regex causando que los datos se pierdan. Sí, eso es exactamente correcto. Y eso es en realidad por qué esto no es genial porque si dijera, hey, esta es mi fecha y es un objeto de fecha, entonces mi cargador está bien con eso. Como puedo decir fecha, nueva fecha. Como eso funciona bien. Pero aquí, si intentara decir post date punto to local string, lo que sea, eso va a arruinar mi aplicación porque se serializó a través de la red. Así que por eso no queremos que uses el genérico como funciona hoy, no, como que técnicamente te estás engañando a ti mismo porque lo es porque esto se serializó, sucedió a través de la red. Tendrías el mismo problema en cualquier caso, independientemente de si estás usando Remix, vas a convertir en cadena las fechas y otros objetos como ese. Y por eso, cuando tengamos el soporte para el tipo de cargador, lo que hará es decir cualquier cosa que esté en el cargador data o en lo que devuelvas de JSON, cualquier cosa que pongas allí se convertirá en una versión JSON en cadena de ese objeto en cuanto a los tipos se refiere. Esto lanzará un error de tipo en el futuro. Y así, sí, la forma en que resuelvo esto es si vamos al repositorio de FakeBooks nuevamente, porque mostramos fechas en varios lugares. Es que, ¿dónde está? En mi cargador. En realidad lo formateo en el servidor y solo envío el valor formateado. También podrías serializarlo o algo así, sí, serializarlo y deserializarlo en el cliente si quieres, como quieras lograr eso, pero sí, debes pensar en el hecho de que todo lo que pases a JSON se convertirá en cadena JSON. Así que tenlo en cuenta.

Oh sí, hablando de pruebas de una aplicación de Remix. No necesitas probar una aplicación de Remix porque cuando escribes una aplicación de Remix, escribes código perfecto. Nunca tienes errores. Simplemente no existen. Solo estoy bromeando. Eso es una broma total. Sí, probablemente no tendremos tiempo para hablar de pruebas. Pero las pilas ya vienen preconfiguradas con herramientas de prueba y cosas así. Entonces, sí, si comienzas con una pila, tendrás todas las cosas de pruebas configuradas. De acuerdo, sí, Chris, y luego pasaremos a otra cosa. Solo una pregunta rápida, en general. Solo quiero saber si es posible tener el cargador que tienes en todos tus componentes, si es posible replicarlo de manera general para poder aplicar algo como una comprobación de estructura o una validación de esquema, cualquier dato que llegue para poder demostrar que esto es definitivamente válido y puedo confiar en la estructura o mostrar un mensaje de error general. ¿Sería eso posible en absoluto? Sí, lo que estás pidiendo es una forma de decir como validar algo y hacer algo como una función de orden superior. Esto no está permitido porque estamos tomando este archivo, estamos creando dos compilaciones diferentes a partir de él y una para el servidor y otra para el cliente. Y para poder deshacernos del código solo del servidor, no puedes tener efectos secundarios en tu módulo. De lo contrario, no podemos estar seguros de que estamos haciendo lo correcto. Y así, las funciones de orden superior no están permitidas. Podrías crear totalmente tu propio JSON y hacer lo mismo allí. Probablemente eso es lo que haría. De acuerdo, solo me preguntaba porque mencionaste esto antes del cargador, esperaba que hubiera algo como después del cargador, tal vez eso sería bueno. Tenemos en el archivo de entrada del servidor, esto maneja las solicitudes para la página inicial. Y así eres responsable de crear el marcado y todas esas cosas, lo cual es realmente agradable. También tenemos una función handle data request. Creo que así se llama. Pero esta es la última parte de tu código que se llama antes de que llegue la respuesta de data. Y sí, así podrías hacer ese tipo de cosas allí. Genial, vamos a continuar con el espectáculo. Entonces, si miramos nuestro esquema, tenemos enrutamiento anidado, carga de data. Voy a mostrarte rápidamente los parámetros dinámicos. Es bastante sencillo y nos ahorrará un poco de tiempo. Así que si miramos las rutas de publicaciones, oh, eso es el ejercicio. Veamos la versión final de eso. Rutas publicaciones, entonces verás, tenemos esta cosa de dólar slug punto TSX. Así es como se hace un parámetro en la URL. Entonces vas a publicaciones slash cualquier cosa y el dólar slug será simplemente el valor que estaba en la URL. Y luego tienes acceso a eso a través de params. Y lo interesante de esto es que, espera, ¿me salté algunas cosas? Sí, hmm, ¿deberíamos? Sí, no tenemos tiempo. Y ya hemos pasado la mitad. Así que eso es todo sobre los parámetros dinámicos. Le das un dólar, como quieras llamar al parámetro y luego en tu código, usas los parámetros en el cargador.

Parámetros, Base de datos y Ejercicio Siguiente

Short description:

Para acceder a los parámetros en tu componente, usa use params de RemixRun React. TypeScript no puede saber si el slug estará definido, por lo que usamos la función invariant para verificarlo y proporcionar un mensaje de error específico. También movimos la conexión a la base de datos a un archivo separado usando Prisma para acceder a los datos en la base de datos SQLite. Recuperamos las publicaciones usando las funciones find many y find unique de Prisma. Si la publicación no existe, lanzamos un error. Si existe, compilamos el Markdown en HTML usando Marked y lo renderizamos. El siguiente ejercicio cubre el enrutamiento anidado y las mutaciones, que son los temas más importantes. Asegúrate de estar en el directorio correcto y ejecuta node dev exercise 04 en el puerto 4004. No automatizaremos la verificación de los parámetros en los cargadores porque sería difícil enseñarle a TypeScript nuestra convención. Estamos agregando una sección de administración a la aplicación y habrá un enlace a ella.

Para acceder a ellos en tu componente, usa use params de RemixRun React. Lo cual es lo mismo que usarlo desde React Writer. Así que si estás familiarizado con eso, eso es eso.

Entonces eso es todo para los parámetros. Ahora, un par de notas. Por un lado, TypeScript no tiene forma de saber si este slug estará definido. Por eso estamos usando esta función invariant. Esta función invariant, si no estás familiarizado con ella, es básicamente lo mismo que esto. Y lo que hace por nosotros es, en primer lugar, nos proporciona un mensaje de error más claro que no se puede llamar a toUpperCase de indefinido o algo así. Así que podemos tener un mensaje de error más específico porque no hay forma de garantizar al 100% que esto será lo que pensamos que es porque podríamos cambiar esto, como escribir mal esto como slugs, y ahora el nombre del parámetro ha cambiado. Por eso, es una buena idea hacer esta verificación. Y cuando haces esta verificación, TypeScript también considerará esto como una cadena, mientras que antes podría ser una cadena o indefinido. Así que eso es de lo que se trata la función invariant. Y verás que uso invariant bastante seguido solo para decir, hey, sé que es, o creo que es de este tipo. Verifiquemos eso, y si no es así, obtendremos un buen mensaje de error para eso. Así que eso es todo sobre eso.

Lo otro que cambió aquí es que omitimos la parte donde conectamos nuestras publicaciones a una base de datos real. Y aquí, estamos usando Prisma para acceder a los datos en la base de datos SQLite. Y moví todo a este otro archivo porque cuando estamos hablando con una base de datos, me gusta poner esas cosas en un archivo separado la mayoría de las veces. Y aquí está mi modelo para comunicarme con la base de datos. Y así, movimos esto al directorio de modelos. Y sí, para obtener las publicaciones, decimos Prisma post find many, y para obtener una específica, decimos find unique donde el slug es lo que estás buscando. Y en esa página de slug, podemos decir, obtener publicaciones, params.slug. Y si eso no existe, entonces lanzamos un error y decimos, hey, eso no existe. Tenemos un mejor manejo de errores en la gestión de 404 que hablaremos más adelante si tenemos tiempo. Pero por ahora, simplemente lanzaremos un error si la publicación no existe. Y, pero si existe, entonces usaremos Marked para compilar el Markdown en HTML. Y enviamos eso a través de la red, y luego renderizamos ese HTML para la publicación. Y así, cuando terminemos ese ejercicio, si vamos a node-dev, sí, vinyl03, ¿qué pasó? Oh. Ahí vamos. Ah, dev, vinyl03, ahí vamos. Entonces, cuando todo eso esté listo, oh, está en la página equivocada de nuevo, entonces terminamos con algo que realmente funciona. Mi primera publicación, esta es mi primera publicación, ¿no es genial? Y aquí está mi mixtape. Y todo eso proviene de la base de datos. Eso debería estar predefinido automáticamente a través de nuestro script de inicialización, que inserta los datos de la publicación en la base de datos cuando configuramos el proyecto por primera vez. Así que de todos modos, así es como funciona esa parte. ¿Alguna pregunta sobre los parámetros o cómo funciona la parte de la base de datos, podemos hablar brevemente sobre eso. De acuerdo, genial. Así que los parámetros, hurras. Cada aplicación los necesita. Bastante sencillo. Así que podemos saltar eso. El siguiente ejercicio es el enrutamiento anidado. Creo, lo que quiero asegurarme de cubrir es el enrutamiento anidado y las mutaciones. Si llegamos a la mejora progresiva, eso es bueno, pero estos dos son los más importantes. Así que definitivamente vamos a cubrir estos dos, al menos. Entonces, sí, número cuatro. Asegúrate de estar en el directorio correcto. Así que estás en para el enrutamiento anidado. Consulta el README allí para el inicio y detención, y ejecuta node dev exercise 04. Y así estarás en el puerto 4004. Y ahí es donde vamos a trabajar, ¿de acuerdo? ¿Alguna pregunta antes de dejarte con esto? De acuerdo, genial. Responderé, Katerina acaba de hacer esta pregunta sobre automatizar la verificación de los parámetros en los cargadores. Sí, no tenemos planes de automatizar esa verificación por ti. Sí, la verificación no ha sido realmente, en mi experiencia construyendo aplicaciones de Remix, no ha sido un problema para mí. Literalmente es solo esto, y creo que vale la pena. Automatizar esa verificación, sería difícil porque implicaría supongo, el problema es que tendríamos que enseñarle a TypeScript nuestra convención, y eso no va a suceder. Como, entonces podrías automatizar la verificación para el tiempo de ejecución, pero nunca podrías automatizarla para TypeScript, y TypeScript vale una línea en tu cargador. Así que sí, probablemente nunca lo hagamos. ¿No sería una idea si, sí, sabes que el slug tiene que ser el dólar, lo que sea que pongas detrás de él. Si eso no está en los parámetros, entonces es inválido, ¿no? Sí, sí, totalmente. Así que podríamos hacer algo en el tiempo de ejecución. Pero nuevamente, incluso si hiciéramos eso, obtendrías un error de tipo justo aquí porque TypeScript no sabe que hiciste eso. Bastante justo. Sí, así que, así que probablemente, probablemente nunca habrá algo así. Varias personas terminaron, así que hagámoslo. Estamos agregando una sección de administración a nuestra aplicación, y así que vamos a tener un enlace a eso. Creo, no recuerdo si esta es la sección donde realmente lo limitamos a usuarios conectados. Creo que eso está en la tarea. Así que puedes hacerlo más tarde.

Creando Sección de Administración con Enrutamiento Anidado

Short description:

Creamos una sección de administración con enrutamiento anidado en Remix. La ruta de administración maneja todas las rutas y subrutas relacionadas con la administración. Renderizamos el outlet para las rutas secundarias. Cuando no hay segmentos secundarios, se muestra la ruta de índice. Al hacer clic en 'crear una nueva publicación', se muestra un error 404 porque falta el archivo new.tsx. Creamos el archivo new.tsx y renderizamos el contenido de 'nueva publicación'. Se pueden usar múltiples rutas anidadas sin bloquearse entre sí.

Pero sí, solo necesitamos crear la sección de administración. Esta primera parte es un poco rutinaria para nosotros. Ya lo hemos hecho antes. Así que si vamos al índice de publicaciones, lo colocaremos justo debajo de las publicaciones. Y vamos a localhost 4004. Ahí están nuestras publicaciones de administración. Y esto dice, publicaciones no encontradas, porque eso no es una publicación. Y vamos a crear un admin.tsx. Y ahora tenemos una ruta para manejar eso. Y en lugar de ir al slug, irá directamente a la página de administración. Así que vamos aquí, y copiamos todo el JSX, y otras cosas que ya sabemos cómo hacer allí. Y si venimos aquí y actualizamos, entonces boom, tenemos una lista de nuestras publicaciones. Y luego tenemos un punto, punto, punto aquí en el lado derecho. Así que esta será la ruta principal para todas las rutas y subrutas de administración más allá de eso. Así que tenemos la publicación listada aquí, y notarás que el enlace apunta al post.slug. Así que aquí no hay combinación de rutas. No tenemos que hacer slash lo que sea y combinar esto. Solo queremos que este enlace vaya de slash post slash admin a slash post slash admin slash slug. Y aquí es donde entran en juego las rutas relativas. Y eso es una característica de React Writer Rev6. Por supuesto, también está en Remix, así que eso es genial. Pero para poder manejar eso, esto será una subruta de la ruta de administración en sí, y aquí es donde queremos que vayan las rutas secundarias. Así que renderizamos ese outlet allí. De acuerdo, así que lo traemos de Remix run React. Y cuando hago clic en estas diferentes rutas, obtendré un error 404 no encontrado porque no tengo una ruta para manejarlas. Whoa, acabo de perder eso. A veces, cuando deslizo hacia la izquierda y hacia la derecha así, mi pantalla se bloquea y no entiendo por qué. De acuerdo, de todos modos, eso nos lleva hasta ahí. Vamos a hacer nuestra ruta de índice para cuando no estemos en una ruta secundaria. Entonces, si estamos solo en admin, ¿qué queremos que aparezca aquí? Y para nosotros, simplemente vamos a decir, crear una nueva publicación. Así que voy a crear un directorio llamado admin y luego un archivo llamado index.tsx allí. Así que ahora, si vengo aquí, esto aparece aquí. Así que esto es como enrutamiento anidado, ¿verdad? Tenemos nuestra ruta de administración. Esa es nuestra estructura para todo. Y luego nuestra ruta anidada dentro de eso, que es el índice de lo que aparece si no tenemos ningún hijo, entonces esto es lo que se mostrará. Esto crea una nueva publicación. Si hago clic en eso, ahora obtendré un 404 porque no tengo un archivo en new.tsx. Así que vamos a crear eso, new.tsx. Y luego vengo aquí. Oh, cierto. Ya hice lo del outlet. Así que ahora estábamos diciendo que aquí es donde van mis hijos. Ahora, para nuestra nueva publicación, esto es todo lo que nos importa poner ahí. Así que nueva publicación. Hooray. Ahí está. Genial. Así que si voy a admin, veré esto como mi ruta de índice. Así que no tengo, no hay segmentos secundarios. Así que muestra esto. Y cuando hay un segmento secundario, se agregará slash new, luego la nueva subruta es lo que se mostrará. De acuerdo. Genial. Creo que eso es hasta donde llegamos. ¿Es hasta donde llegamos? Sí, no creo que hayamos llegado más lejos. ¿O llegamos a las acciones? No puedo recordar. ¿Dónde estábamos? Dijimos detenernos en las acciones. Sí, de acuerdo, genial. Sí. Entonces, ¿qué preguntas tienes sobre el enrutamiento anidado? ¿Puedo tener un ejemplo de eso? Puede que tenga uno. Si tienes múltiples rutas anidadas, ¿se bloquean entre sí o no? Sí, y en realidad tenemos, tenemos múltiples rutas anidadas. Así que tenemos nuestra ruta raíz que en realidad... No lo investigamos, pero si miras el archivo root TSX, eso es responsable de renderizar todo desde la apertura de HTML hasta el cierre de HTML. Así que como toda la página. Esto es realmente genial, porque en mi sitio controlo una clase basada en el estado. lo cual es divertido. Normalmente tienes que usar un use effect para controlar cualquier cosa en el HTML, porque nos gusta hidratar solo el body o lo que sea. Pero sí, eres responsable de todas las cosas y esto renderiza un outlet. Y luego, cuando estamos en la página de publicación, no lo tenemos aquí porque estamos aprovechando el valor predeterminado, pero eso es simplemente otro outlet. Y luego en el administrador, tenemos nuestro tercer outlet.

Manejo de solicitudes POST y creación de publicaciones

Short description:

En el ejercicio 5, continuamos desde la parte anterior y discutimos el manejo de solicitudes POST y la creación de publicaciones en la base de datos. Utilizamos la API de datos del formulario para acceder a los datos del formulario de la solicitud y crear una nueva publicación con el título y el Markdown proporcionados. Luego redirigimos a la página de administración. Remix nos permite manejar fácilmente las solicitudes POST y realizar operaciones en la base de datos.

Tenemos cuatro rutas que se están renderizando en la página. Una para la raíz, una para las publicaciones, una para el administrador y otra para la nueva publicación. Y sí, en el renderizado del servidor, cada uno de sus cargadores bloqueará la carga inicial de la página. Y la mayoría de las veces eso es lo que quieres porque quieres cargar toda la página sin ningún spinner de carga en su lugar. Pero a veces tienes algunos data que son muy lentos o no son importantes o lo que sea. Y eso es lo que la API diferida nos dará en las próximas semanas o simplemente puedes usar la función UseFetcher actual y cargarla solo en el cliente. Creo que tal vez me perdí tu pregunta. ¿Eso responde a la pregunta que tenías? Sí, en su mayoría sí. Entonces, si es bloqueante o con la diferida, si usas el data de Max para obtener los data de tus padres en la interfaz de usuario, tendrías que considerar si se ha obtenido o no o me equivoco? No, cuando se renderiza tu componente, todos los data están listos. De acuerdo. La excepción a eso es la API diferida. Entonces, si estás usando la API diferida, hay un componente especial que usas para lo que se debe renderizar mientras esperamos que ese data esté disponible. Pero sí, sí, supongo que sigamos con el siguiente ejercicio. Así que estamos en la mutación 05 y vamos a partir de las acciones y avanzar hasta la mejora progresiva en nuestro blog de desarrolladores así que continuaremos desde donde estamos. Te doy toda la ruta del formulario nuevamente, no estamos aquí para aprender React y JSX, estamos aquí para aprender Remix. Y sí, la única parte de Remix de esto es el componente de formulario y hablaremos de eso cuando volvamos a reunirnos. Y luego tenemos un poco de código para ti para el Prisma. Y sí, luego hacemos algunas cosas interesantes con TypeScript y manejo de errores y cosas así también. Creo que te gustará este y esto destaca muchas de las cosas geniales sobre Remix también. Así que sí, diviértete con esto y dejaré otro mensaje en el discord para que me avises cuando hayas terminado con esto. Quiero asegurarme de estar en el lugar correcto. ¿Continuamos con esto, o pasamos a uno de los otros ejercicios? Sí, ve al ejercicio cinco. Lo bueno de los ejercicios es que si te equivocas en algo, pero no lo sabes, simplemente pasas al siguiente y no importa. Así que. Gracias. Sí. Sí, así que debería estar ejecutando el ejercicio cinco. Debería estar en el puerto 4005. Así que hagamos esto de las mutaciones. Primero, tomamos este código del formulario y lo que nos queda es el formulario aquí. Esto es genial porque todo está anidado y el enrutamiento anidado es increíble. Realmente hace un gran impacto en lo fácil que es construir estas interfaces de usuario donde no tienes un componente de diseño o algo así. Así que este formulario aparece en cada uno de ellos. Tenemos los títulos en Markdown. Veamos qué sucede cuando enviamos esto sin hacer nada más. Si digo nuevo título, esto es genial. Tal vez podríamos generar eso en algún momento y nueva publicación cuando presiono crear publicación, obtendremos un 405 método no permitido. Y eso es porque lo que hicimos o lo que hace Remix es hacer esta solicitud POST y esa publicación a la URL especial en la URL actual con este parámetro de consulta que define cuál fue la ruta que envió la solicitud. Entonces, así es como Remix puede enrutar eso a la acción que definimos aquí pero no definimos ninguna acción. Entonces no hay nada aquí para manejar esa solicitud y es por eso que obtuvimos un 405 no permitido porque manejamos las solicitudes GET si queremos llegar a esta página pero no manejamos una solicitud POST. Entonces eso es lo que vamos a hacer vamos a manejar esta solicitud POST. Entonces, vamos a, en realidad aquí, asegurémonos de seguir el camino correcto. Entonces sí, primero queremos crear una forma de crear una publicación en la database. Entonces vamos a ir a nuestro servidor de publicaciones en los modelos. Simplemente agregamos esta función crear publicación, podemos agregar los tipos más tarde. Y luego vamos a agregar esta acción y hablemos de esto aquí. Entonces, tomamos crear publicación de nuestro servidor de publicaciones y tenemos nuestra acción que acepta una solicitud. Entonces vamos a obtener un subrayado rojo aquí hasta que agreguemos algunos tipos. Así que voy a agregar esos tipos ahora mismo porque el subrayado rojo me molesta. Esta es una función de acción y eso proviene de remix run node. Y ahora nuestra solicitud es simplemente el objeto de solicitud. Y como recordatorio, esta solicitud es una solicitud fetch web. Entonces, si profundizamos en la definición aquí y vamos a las solicitudes, esto proviene literalmente de la interfaz de la API fetch para solicitudes. Como este es el objeto de solicitud global. Y probablemente esté completo para nosotros en node a menos que estés usando la última versión de node. De hecho, creo que ni siquiera lo llenamos allí o creo que probablemente lo llenamos allí también tal vez porque por razones. Pero en cualquier caso, puedes tratar esto como una cosa fetch web normal. Y muchas personas que usan remix se encuentran pasando mucho más tiempo aquí que aquí. Más tiempo en MDN que en la documentación de remix. Esto es realmente genial porque significa que a medida que te conviertes o usas remix te conviertes en un mejor desarrollador web y no solo en un mejor desarrollador de remix. Y esto es lo que me gustó de React. Sentí que me estaba convirtiendo en un mejor desarrollador de React o un mejor desarrollador de JavaScript no solo un mejor desarrollador de React en comparación con lo que estaba haciendo con AngularJS y cosas así. Entonces sí, esto es una cosa fetch web y vamos a usar la API de datos del formulario. Entonces, nuevamente, si vas a mdn.io y escribes y pasas cualquier cosa esto realmente hará una búsqueda rápida y te redirigirá a la página en developer.mozilla.org que coincida con esa cosa, el FACET. Así que voy a mdn.io/stuff todo el tiempo. Así es como hago búsquedas para cosas web. Pero de todos modos, request.formdata es una API que te brinda acceso a los datos del formulario de la solicitud, lo cual es perfecto. Ahora tenemos el objeto de datos del formulario. Podemos obtener el título, SLAG y el Markdown y crear la publicación con eso. Luego vamos a redirigir a post/admin porque eso es lo que tiene más sentido.

Manejo de creación de publicaciones y actualizaciones de datos

Short description:

Podemos redirigir a los usuarios a la página final después de crear una publicación. Remix maneja la redirección solicitando datos para la nueva página y luego enviando al usuario allí. Esto elimina la necesidad de actualizaciones manuales de datos y simplifica la gestión del estado. Remix vuelve a validar automáticamente los datos en las mutaciones, asegurando que se muestre la información más reciente.

También podríamos redirigir potencialmente a post slash, ya sabes, post, o sí, SLAG. Así los llevamos a la página terminada real, como la publicación que acaban de crear. Pero tal vez quieran escribir otra publicación, no sé. Puedes hacer lo que quieras allí para redirigir. Pero eso es lo básico de cómo manejar eso. Y así que si venimos aquí y en realidad, antes de hacer esto, echemos otro vistazo al índice o lo siento, a la ruta de administrador, nuestra ruta principal. Esto está renderizando todas nuestras publicaciones. Ahora, quiero que prestes atención a qué código no está aquí. No hay código aquí para actualizar la publicación cuando creamos una nueva publicación. No hay nada, de acuerdo. Simplemente estamos diciendo, cualquiera que sea la publicación que tenga, muéstrala. Y luego aquí tenemos un poco de código para crear una nueva publicación y luego redirigir a post slash admin. Entonces, si creo una nueva publicación, vamos a decir, Sandrina es genial, y luego ah, Sandrina, ah, sabe cosas increíbles, ah, sobre accessibility. De acuerdo, ahora decimos crear publicación. Quiero que observes la lista aquí y veas qué hace la pestaña de red. Crear publicación, boom, ahí está. Así que nos hemos redirigido a post admin. Hicimos la publicación aquí. Ah, y Sandrina es genial, está aquí a la izquierda ahora. Así que no tengo código. Recuerda, no hay state management. No estás pensando en eso. Todo se actualiza automáticamente. Es increíble. Así que creamos la publicación y luego Remix dice, oh, esto se va a redirigir. Así que miramos la respuesta. Bueno, sí, esto es una redirección de XRemix. Como Remix solo emula el navegador, en realidad no obtendrás una redirección aquí mismo porque no quieres que el navegador vuelva a cargar esta página. Y así Remix dice, oh, quieres que vayan a esta página de administrador? Bueno, resulta que sé que la página de administrador tiene un par de rutas que tienen cargadores. Así que voy a solicitar esos data. Y si miras esto, eso está sucediendo todo al mismo tiempo. Voy a solicitar esos data. Entonces, en ese momento, puedo enviar al usuario a esa página. Y esto es realmente genial porque significa que nunca tenemos que mantener nuestros data actualizados. Y por eso no necesitas preocuparte por la gestión del estado. Entonces, cuando se realiza una mutación, Remix dice, de acuerdo, todas las apuestas están canceladas en los data que tenemos aquí. Vamos a actualizar todos los data en la página. Ahora, sé que algunos de ustedes están pensando, oh no, no puedo actualizar todos los data en la página cada vez que al usuario le gusta un tweet o algo así. Hay absolutamente APIs para que puedas decir, hey, no quiero esta actualización automática de data. Pero ten en cuenta que la forma en que el navegador siempre se ha comportado es que cuando haces una mutación, haces una actualización completa de la página. Haces la mutación, y luego creas un nuevo HTML basado en lo que está en la database actualmente. Así que siempre obtienes la información más reciente y actualizada. Así que eso parece un valor predeterminado bastante sólido. Y esto es lo que nos permite mantener el modelo mental de finales de los 90, principios de los 2000 de construir aplicaciones web porque Remix vuelve a validar automáticamente tus data cuando se realiza una mutación. Así que eso es las mutaciones con Remix.

Controles complejos y gestión del estado

Short description:

Para controles más complejos como un grupo de radio que requiere estado para el estilo, se puede utilizar useState en Remix. Sin embargo, Remix elimina los desafíos de gestionar el estado de la aplicación en aplicaciones React, como las condiciones de carrera y las actualizaciones de estado complejas. En el futuro, con has en CSS, es posible que incluso controles más complejos no requieran estado.

Entonces, lo que me preguntaba cuando trabajaba con foros, era cómo hacer algo más, y tengo claro cómo hacer controles simples como un campo de texto, una casilla de verificación. Pero si quieres algo más sofisticado como un grupo de radio, que no sean solo botones de radio simples, sino algo en el que necesites estado para el estilo. Estoy pensando en algo como poner un enlace en el chat, algo como el grupo de radio de la interfaz de usuario headless. ¿Cómo lo harías? Porque como veo ahora en los foros, siempre tenemos estos controles simples sin ningún estado local pero que requieren estado, porque necesitas estilizar todos los elementos que lo rodean, ¿verdad?

Sí. Primero diré que creo que podremos hacer esto sin estado en el futuro porque haz está llegando a CSS. Y sí, eso será genial. Pero sí, ahora mismo eso no es posible. Así que sí, no veo nada aquí que no funcione bien con remix. Puedes usar useState perfectamente y con remix, eso funciona bien. Entonces, sí, no estoy diciendo que nunca usarás useState en remix pero no lo necesitas para que la aplicación funcione. Lo difícil del estado en las aplicaciones de React no es este tipo de estado. Este tipo de estado es fácil. Cualquiera puede hacer esto. Lo difícil es el estado de la aplicación donde, bueno, acabo de agregar esta publicación y ahora tengo que actualizar esa lista y todo el estado que se gestiona allí. Así que ahora tenemos que compartir algún contexto. Y ahora tenemos reductores y despachos y cosas así. Y oh, bueno, ¿qué pasa si lo actualizo antes de que realmente termine y luego se cancela la solicitud o el usuario... Hay una condición de carrera. Hay tantas cosas que hacen esto realmente difícil. Remix elimina esas cosas difíciles. Cosas fáciles como esta, sí. Todavía puedes usarlo totalmente y funciona igual de bien. Pero sí, en el futuro, tendremos has en CSS e incluso algo como esto, no necesitarías estado, lo cual sería genial. Así que buena pregunta, Felix.

Manejo de Actualizaciones de Formularios y Manejo de Errores

Short description:

Para actualizar el valor de un formulario, como botones de radio o casillas de verificación, puedes usar el hook useState en Remix. Al establecer el tipo de entrada en oculto y proporcionar un nombre y un valor, puedes serializar la opción junto con otros datos del formulario. Las rutas y plantillas en Remix son similares, pero Remix ofrece más flexibilidad al permitirte usar funciones de JavaScript como componentes. Para cargar datos adicionales basados en una selección en un menú desplegable anidado, puedes usar el hook useFetcher en Remix. Este hook te permite hacer una solicitud POST a una ruta específica, manejar la solicitud en una acción y actualizar las opciones basadas en los datos de respuesta. El manejo de errores en Remix se puede hacer enviando un mensaje de error desde el servidor al cliente y mostrándolo al usuario.

Esa es una buena idea. Todavía no estoy seguro de cómo actualizarías entonces los forms, ¿el valor? Porque si tienes un control simple como botones de radio o casillas de verificación, entonces el navegador mantiene el estado de si está marcado o no. Y si controlas el estado, ¿cómo lo pasas al formulario, por así decirlo? Sí, gran pregunta. Me sorprendería mucho si no tienen un botón de radio real en algún lugar aquí. Porque si no lo tienen, entonces es muy difícil hacerlo accesible. Probablemente haya un botón de radio que se está representando en algún lugar. Si no lo hay, oh sí, tienen un rol de radio. Sí, eso es desafortunado. No sé por qué no representan un botón de radio real. Pero esto es lo que haces. Dirías, aquí está mi useState, o diremos opción. Oh, genial, lo arruiné. Ok, intentémoslo de nuevo, useState, opción. Entonces, como, aquí está mi sándwich o mi sándwich, seguro. Y luego dentro de aquí, simplemente dirías input, tipo, oculto, nombre, opción, y luego valor como opción. Y ahora se serializará junto con todo lo demás. Ok, eso es una gran idea, genial. Sí, algunas de las personas que han estado aquí durante un par de años dicen, oh sí, recuerdo cuando solíamos hacer eso. Es verdad. Sí, volviéndolo a hacer, genial. Gran pregunta.

Otras preguntas, veo a MightyHake, ¿así se pronuncia tu nombre? Sí, muy bien. Sí, no estoy seguro si se respondió antes pero las rutas y las plantillas son algo similar aquí, ¿no? ¿Y qué pasa si quieres usar una plantilla en una ruta diferente? Sí, lo que es genial de esto es que es más poderoso que las plantillas porque es solo JavaScript, es como un lenguaje completo, y así que si dices, ¿sabes qué? Me gusta mucho esta etiqueta, entonces simplemente conviértelo en un componente de función. Y así dices, oh, quiero hacer esto una función llamada, sí, mi componente de etiqueta y ahora puedes usarlo en cualquier lugar. De acuerdo, genial. La magia de React es bastante, bastante genial. Genial, Chris. Sí. Oye, una pregunta rápida sobre cómo harías un menú desplegable anidado. Así que imaginemos un ejemplo. Tienes una lista de países y una vez que seleccionas un país, te gustaría tener otro menú desplegable que cargue datos para todas las ciudades. Quiero decir, es un ejemplo sin sentido, pero ¿cómo cargarías datos adicionales en el formulario basado en esta selección? Sí, esa es una súper pregunta. Te estás adentrando en cosas más avanzadas. Pero te mostraré lo que hacemos. Esto es el material para el taller avanzado, que daré mañana y pasado mañana. Así que, y probablemente todavía haya entradas. Así que si quieres inscribirte, podría ser divertido. Pero sí, si vamos a... Oh, ¿dónde estaba? Sí, esta es la ruta. Entonces, estoy usando... Tengo esto en realidad, te mostraré cómo se ve. Libros falsos. Vamos a ventas. Y si quiero crear una nueva factura, ahora tengo este cuadro combinado. Y está impulsado por data basada en los clientes que tengo. Y así puedes hacer lo mismo, como múltiples de esos son selectores basados en la opción anterior. Pero todo eso, eso va a tomar un estado de UI que estás gestionando, ¿verdad? Entonces, cuando seleccionen esto, ahora vamos a actualizar estos. Pero la forma en que esto funciona es que tenemos este componente de cuadro combinado que está usando este hook useFetcher. Esto es de Remix. Y useFetcher se enviará. Así que hará una solicitud POST a esta Acción, que en realidad es donde se encuentra este archivo. Entonces, donde se encuentra este componente. Así que simplemente hará una publicación a esta ruta. Y enviará la consulta. Y luego la Acción que está aquí se llamará y podemos hablar con la database, hacer lo que queramos, enviar la respuesta de vuelta. Y luego cuando ese Fetcher tenga data, eso es lo que se utilizará para alimentar qué opciones están disponibles. Así que solo haces eso mismo. Esto en realidad no es una convención muy normal o no es una convención documentada porque cuando estaba preparando el material del taller, se me ocurrió la idea de que, ¿qué pasa si tomamos la ruta de recursos y ponemos el componente que lo usa en el mismo archivo? Y así, sí, el hecho de que exportemos esto, eso no es una convención. Como puedes exportar lo que quieras de un módulo. Y así que simplemente lo importamos en, ¿dónde está? Creo que es, sí, clientes, o no, es facturas nuevas. Sí, si vamos al cuadro combinado de cliente y luego simplemente lo renderizamos y luego podemos enviar un error por ejemplo, así cuando se envía esto, si hay ese error, o si hay un error al enviarlo, enviamos el error al cuadro combinado de cliente para que lo muestre de manera agradable o lo que sea, pero sí, está totalmente aislado del resto de esa página, así que es todo como, aquí está todo para este componente, incluido el código del backend para este componente, todo en un solo lugar, es realmente agradable. Así que sí, la respuesta corta es usar Fetcher. De acuerdo, genial, gracias. Genial, ¿alguna otra pregunta? Sí, tenemos una ampliación de la pregunta anterior. Así que responderé a esa primero. Me preguntaba si podrías hacer un manejo de errores con la función createPost. Todavía estoy confundido, ¿estás diciendo si hubo un error al crear la publicación? Sí, exactamente. Lo siento, no estoy articulando bien la pregunta. Sí, está bien.

Manejo de Errores y Redirecciones

Short description:

Al manejar errores en Remix, tienes la opción de usar un componente de límite de error para capturar y manejar errores inesperados. El límite de error puede estar anidado dentro del componente o ruta donde pueda ocurrir el error. Al agregar el límite de error, puedes evitar que el error afecte a toda la aplicación. No es necesario redirigir después de una mutación para actualizar la interfaz de usuario. Cuando ocurre una mutación exitosa, Remix vuelve a cargar automáticamente todos los datos en la página. Esto asegura que la interfaz de usuario se mantenga actualizada sin necesidad de actualizaciones manuales. Si no se realiza una redirección después de una mutación, es posible que el navegador solicite al usuario que vuelva a enviar el formulario si regresa a la página. Este comportamiento se puede evitar utilizando una redirección después de una mutación exitosa.

Me preguntaba si tienes que manejar, por ejemplo, si Prisma tiene un error, ¿dónde manejas eso, y cómo lo transfieres de vuelta al cliente para poder manejarlo, mostrarlo al usuario? Sí, totalmente. Así que tienes un par de opciones, y en este ejercicio, entramos en la respuesta de datos de la acción aquí para los errores de lo que el usuario ingresó. Pero estás hablando de, como, ¿qué pasa si yo soy el culpable? Como, cometí un error. Así que no hablamos de manejo de errores en esta guía, pero el tutorial de JokesApp aborda tanto los errores esperados, como 401, 404 y cosas así, como los errores inesperados. Entonces, como, algo explotó, metí la pata. Y la solución es, veamos, usar esta cosa llamada límite de error. Entonces exportas este componente de función que es un límite de error. Dice, metí la pata, lo siento, lo que sea. Y esto también se anidará en lugar de cualquier cosa que esté envolviendo. Así que, en realidad, en el sitio web de Remix en la parte inferior es donde hablamos de errores. Así que agregas el límite de error y en lugar del componente o esa ruta, se renderizará tu límite de error. Así es como funciona eso. También se propaga hasta el límite de error común más bajo. Así es como manejarías eso. Si quisieras intentar capturar ese error para que no explote todo y eliminar el formulario y cosas así, porque eso es bastante razonable, entonces solo seguirías el mismo patrón aquí. Tal vez envolverías eso en un try catch y luego enviarías un mensaje de error que diga, oye, lo siento, metí la pata en algo, lo que sea. Así que sí, si fueras como, sí, mi database es bastante poco confiable o algo así, o en este caso, en realidad no manejamos el caso donde el slug es único. Así que si intentara ahora crear una nueva publicación que tenga el mismo slug que otra, eso también explotará algo, y esto es lo que obtengo sin tener un límite de error en su lugar. Sí, eso sería algo para verificar probablemente. Perfecto, sí, eso traza una línea perfecta hacia tu curso épico de React que ahora tiene sentido, con el límite de error, sí. Genial, gracias.

Pero me preguntaba si quisieras hacer algo sin un formulario, pero tienes un botón que es una acción, ¿puedes hacerlo sin un formulario? Porque supongo que Remix sigue este modelo web antiguo, como dices, donde el estado se gestiona a través del formulario en el servidor y cosas así. Solo estaba, sí, preguntándome. Si, para cosas que no necesitan un formulario, pero aún quieres ese mismo tipo de comportamiento. Sí, esa es una gran pregunta. Iba a mostrarte esto, pero creo que lo envié de vuelta a eso. Así que vamos a ejecutarlo localmente para que pueda mostrarte a qué me refiero, o mostrarte un ejemplo de esto. Así que voy a iniciar el servidor de desarrollo, y se inicia tan rápido. ¿Alguno de ustedes ha notado lo rápido que se inicia el servidor de desarrollo? ¿No es genial tener un servidor de desarrollo que se inicia realmente rápido? Creo que es genial. De acuerdo, así que si vamos a depósitos, vamos a ver un pequeño ícono de basura justo aquí. Así que es como el botón. Y luego voy a hacer clic en eso y lo elimina. Eso es una mutación, ¿verdad? Entonces, ¿cómo funciona eso? Bueno, resulta que esto es solo un formulario. Así que todavía tenemos un formulario, y simplemente envolvemos el botón, o el ícono de basura en un botón, y ese es el botón de envío. Te sorprendería cuántas cosas pueden ser solo un formulario. Y así es como solíamos hacerlo a principios de los años 2000. Así que ten en cuenta, en realidad, que el método sigue siendo POST, aunque en realidad estamos eliminando, porque el navegador solo admite GET y POST. Puedes hacer DELETE aquí, se admite, pero eso va en contra del mejoramiento progresivo porque el navegador no lo admite. Así que simplemente hacemos POST y luego lo manejamos nosotros mismos. Pero en cualquier caso, eso es cómo lo haces si tienes algo visual. Pero tu pregunta me lleva a otra pregunta común, que es ¿qué pasa si quiero hacer una mutación que no involucre interacción del usuario en absoluto? Entonces, en mi sitio web personal, en mi blog, cuando oh, parece que Red está en la delantera. Huh, eso es nuevo, felicidades Red. Cuando vas a una de mis publicaciones de blog, si lees todo, te desplazas por todo, entonces lo cuento y estás en la página el tiempo suficiente, entonces lo cuento como leído y eso es lo que va a las clasificaciones de los diferentes equipos en función del equipo al que perteneces. Y también hago un seguimiento de cuántas lecturas hay en total de si estás conectado o no. Y no quiero que tengas que hacer clic en una pequeña casilla de verificación para decir que lo leíste. Entonces necesitamos hacer una mutación que ocurra sin que realmente hagas nada. Y así es como lo hago con useFetcher. Y useFetcher tiene esta capacidad de crear forms para ese fetcher en particular, que estamos haciendo para este botón de eliminación, pero también la capacidad de decir .submit. Y eso es lo que vimos antes con la cosa del cliente. ¿Dónde está el cliente y los recursos aquí? Así que aquí decimos, oye, fetcher, quiero que envíes para que puedas hacer esa especie de envío sin ninguna interacción del usuario. Así que sí, tu caso de uso está cubierto.

Pregunta rápida, así que en nuestro ejemplo, hacemos una redirección después de terminar de crear la nueva publicación. ¿Esa es la razón por la que se actualiza la lista de publicaciones? Si no es así, ¿puedes explicar rápidamente qué está sucediendo en el fondo? Sí, la razón por la que redirigimos es simplemente porque cuando un usuario termina con su publicación, simplemente suponemos que no quieren hacer una nueva, pero tal vez sí. Entonces, no es necesario hacer una redirección para que la interfaz de usuario se actualice. La razón por la que la interfaz de usuario se actualiza es cuando hay una mutación exitosa, Remix vuelve a cargar automáticamente todos los datos que están en la página, eso es todo. Y así es por qué nunca tienes que preocuparte por mantener tus datos actualizados. ¿Qué devolverías en lugar de eso?

De acuerdo, esta es en realidad una gran pregunta porque si no haces una redirección, déjame apartar esto. Si no haces una redirección, cuando hay una mutación exitosa, entonces terminas en ese lugar divertido donde el navegador, como el usuario presiona el botón de retroceso y el navegador muestra esta cosa que dice, ¿quieres volver a enviar esta presentación de publicación? Y eso es súper, súper molesto que lo haga. Esto solo sucede si JavaScript está desactivado. Si hiciste una solicitud fetch, eso no sucederá. Pero con, así que retrocediendo un par de años, por eso tenemos esa cosa súper molesta y la razón de eso es porque no hicieron una redirección. Y eso significa que la solicitud POST es parte de la pila de historial. Así que tienes get, get, get, post, get, get, el usuario presiona el botón de retroceso. Hacen un get. El usuario presiona el botón de retroceso nuevamente. Hacen un post. Y así que el navegador, durante mucho tiempo, eso es lo que hicieron. Y así que reservabas dos vuelos o algo así. Y así que luego los proveedores de navegadores dijeron, oh, eso probablemente no es bueno.

Solicitudes POST, Manejo de Errores y Datos JSON

Short description:

Al hacer una solicitud POST, se recomienda redirigir a una solicitud GET para evitar múltiples solicitudes GET para cada mutación. Usefetcher se puede utilizar con este propósito, ya que no realiza una transición. El manejo de errores se puede lograr utilizando límites de captura, que renderizan componentes de respaldo cuando falla la carga de datos. Cuando se utiliza una interfaz de usuario anidada, solo se renderizará un componente de respaldo en la página. Es posible renderizar un respaldo con un alcance superior diseñando el límite de captura para renderizar toda la sección de la interfaz de usuario. La función de mejora progresiva en Remix se puede explorar de forma independiente. Los datos JSON se pueden enviar a un punto final de API en lugar de datos codificados en URL utilizando una ruta de recurso y especificando request.json en lugar de request.formdata.

Vamos a advertirles. ¿Quieres hacer esta solicitud POST de nuevo? Y ahora la gente solo dice confirmar porque solo quieren que la cosa desaparezca. Y así que reservan dos vuelos de todos modos. La solución a esto es hacer un get, get. Y luego cuando hacen el post, rediriges realmente. Así que el post no termina en el historial y es solo un get en su lugar. Y así que cuando retroceden, luego obtienen el post. O luego obtienen el get en lugar del post. De todos modos, lo haremos- Así que rediriges a la misma página. Sí, exactamente. Pero el problema con eso es que ahora tienes, si estás haciendo muchas solicitudes, muchas mutaciones, vas a tener un get para cada una de esas mutaciones. Así que tienes una larga lista de historial que es exactamente la misma página una y otra vez. Así que eso no es genial. Si ese es el tipo de cosa que estás haciendo, si dices, no quiero ir a ningún lado. Solo quiero quedarme aquí, entonces ahí es donde usas usefetcher porque usefetcher no hace una transición. Y nuevamente, eso va más allá de lo que estamos haciendo en este taller. Pero la idea es que sí, hemos manejado este caso de uso y es algo de usefetcher. Básicamente, eso es todo lo que es. Así que eso reemplaza a la acción, ¿verdad? No, aún usarías una acción. Lo bueno de usefetcher es que todo lo demás es igual. Entonces, si queremos cambiar esto, tendríamos mi fetcher usefetcher y luego diríamos fetcher.form y todo lo demás funciona. Y aquí, puedes hacer una redirección si quieres. Pero normalmente, si estás usando un fetcher, entonces dirías Json para que el fetcherdata sea lo que pases en el Json. Entonces sí, el modelo mental sigue siendo el mismo independientemente de si estás haciendo una transición con un formulario regular o si no estás haciendo una transición con un fetcher.

De acuerdo, Marvin? Hola, también tengo una pregunta sobre el manejo de errores, si está bien. Sí, nunca he usado Remix antes, pero leí en el descanso acerca del límite de captura que parece ser como el límite de error pero para respuestas incorrectas. Y me pregunto acerca de nuestra aplicación web donde la navegación y un outlet y un outlet mostramos muchos hijos y en cada uno de los hijos mostramos data que debe cargarse pero podría haber algo mal y tenemos que mostrar un respaldo. Entonces podríamos envolver a todos los hijos y un límite de captura y mostrarles un respaldo si alguno de ellos no puede cargar data. Entonces, en caso de que sea solo una vez les mostramos un respaldo y todos los demás hijos aún muestran data podemos usar la navegación y demás, pero ¿qué pasa si todos ellos, todos los cargadores de data fallan entonces preferiría mostrar solo un respaldo para todo el outlet y no muchos de ellos. ¿Hay alguna forma de optar por no tomar el respaldo más cercano y luego mostrar solo un outlet para que podamos seguir usando la navegación y demás? Bueno, ten en cuenta que cuando tienes una interfaz de usuario anidada nunca tienes outlets hermanos. Eso no existe en la interfaz de usuario anidada porque tampoco tienes segmentos de URL hermanos. Como no puedes estar en dos lugares a la vez. Y solo renderizarás un respaldo en la página. Y así que si esta parte de la página es la que tenía un límite de captura, como el usuario no tiene acceso a esta factura o algo así. Y tienes un límite de captura justo aquí. Se renderizará justo ahí. Si no tienes un límite de captura justo ahí entonces simplemente subirá por la interfaz de usuario, por las rutas hasta que encuentre una de esas rutas que tenga un respaldo o un límite de captura y lo renderizará. ¿Eso responde a tu pregunta o me estoy perdiendo algo? Sí, pero estoy pensando en si pudieras volver a la diapositiva anterior, tienes el límite de captura como se muestra allí pero también uno sobre la parte izquierda de la lista de facturas y luego tal vez también sobre esto dinero gastado arriba a la derecha, ¿verdad? Entonces, la mayoría de la página mostraría un respaldo. Y en mi ejemplo solo quiero mostrar un respaldo debajo del encabezado de ventas. Pero si solo falla una carga de data. entonces aún quiero mostrar el más cercano. Pero en caso de que falle la carga de data para cada solicitud realizada en esta página entonces quiero mostrar el respaldo con un alcance superior que está alto en el árbol de componentes. Entendido. Entonces, lo que sucede con al menos la forma en que está diseñada esta interfaz de usuario o la forma en que funciona es que esta sección aquí o esta parte de la interfaz de usuario está controlada por la ruta de facturas. Y luego esta parte de la interfaz de usuario es la ruta del ID de factura. Y luego esta parte de la interfaz de usuario es la ruta de ventas. Entonces, si falla cualquier parte de la carga de data para cualquiera de estos componentes entonces vas a renderizar todo esto como un límite de captura. Así que no hay una parte de la interfaz de usuario en el límite de captura y otra parte en otro lugar. Podrías hacer eso, podrías hacer que funcione donde tu límite de captura renderiza básicamente lo mismo y solo renderiza tanto como sea posible. Y así que eso es totalmente posible, podrías hacer eso. E incluso podría renderizar el outlet para que el hijo, si funcionara, eso funcionaría. Simplemente nunca se me ocurrió hacerlo de esa manera. Pero sí, lo que estás describiendo, puedo ver que funciona. Simplemente nunca lo he intentado.

Permíteme verificar rápidamente que cubrí todo lo que quería. Sé que todavía hay más preguntas, pero déjame verificar rápidamente. Sí, cubrimos las mutaciones. La función de mejora progresiva es genial. Puedes echarle un vistazo tú mismo. Es bastante simple. Es lo que sucede si el JavaScript tarda demasiado o la solicitud tarda demasiado, y luego muestra alguna interfaz de usuario pendiente y demás. Es bastante sencillo. No creo que sea importante cubrirlo. Así que estoy feliz de quedarme aquí y responder tus preguntas, pero sí, puedes guardar el taller porque no vamos a hacer más ejercicios. Así que, y si necesitas irte y demás, está bien, solo antes de hacerlo, si pudieras mirar el archivo leeme en la, como la raíz del repositorio, hay un enlace a un formulario de comentarios del taller, y me encantaría si pudieras proporcionar algunos comentarios. ¿Puedes enviar JSON arbitrario data al punto final de la API para enviar los datos del formulario o debe estar codificado en URL? Sí, puedes enviar JSON data en lugar de datos codificados en URL, si quieres hacer tu propia solicitud fetch. Entonces puedes crear lo que llamamos una ruta de recurso, que es una ruta que solo tiene una acción o un cargador, no tiene una exportación predeterminada. Y en eso, si estás enviando JSON data, entonces en lugar de request.formdata, dirías request.json, y listo, ahora tienes el JSON. Así que sí, eso es totalmente posible. Y podrías hacer eso aquí también, solo que Remix por defecto codificará el formulario como se codifica el formulario, así es como funciona el navegador. Y también hacemos transmisiones y todas esas cosas para subir archivos y demás.

Manejo de múltiples formularios y migración desde Next.js

Short description:

Dos formularios diferentes en la misma ruta pueden ser diferenciados según un campo del formulario. La migración desde Next.js a Remix se puede hacer gradualmente utilizando Express o Nginx para enrutar a diferentes aplicaciones. UseFetcher en Remix almacena en caché los datos utilizando encabezados de caché en lugar de almacenamiento en memoria. Remix puede ser compatible con React Native, lo que permite utilizar el Loader de React Native. La demostración de la aplicación de tareas pendientes funcionando con JS desactivado y una conexión 3G es impresionante y debería destacarse en la página de inicio.

Pero eso, nuevamente, va más allá de lo que estamos buscando, o lo que estamos haciendo en una sub-masterclass. Y dos formularios diferentes en la misma ruta, esa es una gran pregunta. Te mostraré un ejemplo de eso, veamos, formulario. Solo buscando un ejemplo aquí. Sí, bien, en la página del ID de factura de esta aplicación, si vamos a esta factura, tenemos, oh no, solo tenemos un formulario aquí. Oh, debe haber una página donde tengamos múltiples formularios. Sí, arbitrariamente, así se demuestra la interfaz de usuario pendiente. Vaya, bueno, la solución es, estoy seguro de que tengo un ejemplo, pero simplemente no puedo encontrarlo, pero la solución es básicamente diferenciar según un campo del formulario. Y aquí, si miramos la intención aquí, los botones de envío pueden tener un nombre y un valor. Y así, si tuvieras múltiples botones de envío en un solo formulario, puedes decir intención. Y esto es eliminar depósito. Entonces, cualquiera que el usuario haga clic en él, ese será el valor de la intención. Y así puedes diferenciar qué botón hicieron clic. Pero estos también pueden ser formularios totalmente separados, y solo tienes que hacer que el valor de la intención sea el botón de envío. Y luego tu acción puede decir ¿cuál fue la intención? De acuerdo, voy a hacer esto. Oh, hicieron clic en ese formulario. Voy a hacer este otro. Sí, todo es solo cosas web que no tienen nada que ver con Remix. Así es como funciona la web. De acuerdo. Sandrina. Sí, mi pregunta era sobre la migración. Imaginemos que tenemos un código en Next.js, un código bastante grande en Next.js, ¿cómo lo migraríamos a Remix? Sí, esa es una gran pregunta. Hay varias personas en el Discord de Remix que están haciendo esto en este momento. Y probablemente puedan darte respuestas más informativas basadas en su experiencia. Sé que uno de ellos está utilizando Express y tiene Next que se sirve a través de ciertas rutas a través de Express que enruta a la aplicación de Next. Y luego otras rutas serán manejadas por Remix porque Remix se integra perfectamente con Express. Utilizas el adaptador de Express. Y así, a medida que el usuario pasa de la aplicación de Next a la aplicación de Remix o viceversa, hacen una actualización de página completa para pasar de una a otra. Podrías hacer lo mismo con Nginx o algo así. Simplemente enrutar a las diferentes aplicaciones. Y luego con el tiempo, simplemente migras. Esa es probablemente la mejor opción porque el desafío es que Next utiliza un enrutador completamente diferente. Como todo lo demás es muy diferente. Y así que no hay realmente una migración muy sencilla allí. No sé si es posible usar React Router con Next.js, pero probablemente no. Si lo fuera, entonces te migrarías primero a React Router. Y eso facilitaría un poco las cosas. Pero creo que esa es probablemente la mejor aproximación allí, simplemente Nginx que sirve a las diferentes aplicaciones o simplemente usar Express para servir a las diferentes aplicaciones. Y luego migrar con el tiempo de esa manera. Lo bueno es que ambas son React, por lo que no tienes que reescribir todos tus componentes. Pero sí, como la carga de datos y las mutaciones, te encontrarás eliminando un montón de código. Y en realidad, ya he hecho esto antes. Fui uno de los que trabajó en la migración de Remix vs Next, donde tomamos su aplicación para su demo de comercio electrónico y la reescribimos para usar Remix. Así que he hecho una migración de Next a Remix y no es muy divertido, pero es totalmente posible. Sí, aquí hay una pregunta. ¿El UseFetcher almacena en caché los datos? ¿Habría algún caso de uso para algo como React Query, por ejemplo, para poblar opciones desde APIs? Sí, almacena en caché los datos. Entonces, aquí está la cosa. Cosas como React Query almacenan en caché los datos, pero los almacenan en memoria, por lo que puedes navegar, ir aquí, completar esto y luego navegar a otra página y volver y ya está en caché. Eso es lo genial, ¿verdad? ¿Qué pasa si cierras la pestaña del navegador? Bueno, ahora se ha ido. Se ha ido para siempre porque estaba en memoria. Y así, lo que Remix te anima a hacer en su lugar es usar encabezados de caché para que el navegador lo retenga en su propia caché durante el tiempo que desees que esté en caché. Y así, cuando el usuario escribe su consulta, se almacenará en caché según la URL de la consulta. Y sí, ese es el mecanismo preferido para almacenar en caché, simplemente usar la plataforma en lugar de implementar tu propio mecanismo. Entonces, el caso de uso del que estás hablando está bien cubierto. Simplemente se cubre con un enfoque diferente.

¿Hay alguna palabra oficial sobre hacer que Remix sea compatible con React Native, no solo compartiendo componentes, sino utilizando Loader de React Native? Así lo mencioné antes. Creo que podría ser posible tener tu Vista o tus Cargadores y Acciones en el mismo archivo que tus Vistas para React Native. Esto no es una prioridad para nosotros, pero es algo que creo que sería realmente genial y totalmente posible. Así que si alguien quiere experimentar con eso, adelante, porque básicamente podrías tener una compilación especial, tal vez una convención en lugar de un directorio de aplicaciones, tendrías un directorio nativo o algo así. Y luego todo lo demás sería igual, excepto que cada ruta sería una ruta de recurso y luego el formulario simplemente se enviaría a la URL, como la URL completa para esa ruta o algo así. Creo que es totalmente posible. Me encantaría ver a alguien experimentar con eso.

La demostración que mostraste antes cuando desactivaste JS y la aplicación de tareas pendientes sigue funcionando bien con una conexión 3G, es realmente asombroso. Creo que deberías ponerlo en la página de inicio. Estoy de acuerdo.

Demo, Stacks, Caching, and Future Plans

Short description:

La demostración es impresionante. El código está en un solo archivo, alrededor de 600 líneas, incluyendo el código frontend y backend. Remix simplifica el desarrollo, reduce las líneas de código y mejora el rendimiento. Remix Stacks ofrece andamios preconfigurados con herramientas y autenticación de usuarios. La comunidad ha creado numerosos stacks. El almacenamiento en caché en Remix depende del caso de uso y no hay una API para borrar la caché del navegador. Remix se centra en el núcleo de la pila, cerrando la brecha entre el cliente y el servidor. Puede expandirse para incluir más soporte incorporado para modelos de bases de datos. Prisma ya es una excelente herramienta para el acceso a bases de datos. Reach UI es parte de Remix y puede desarrollarse aún más. En el futuro, podrían incluirse características adicionales como un sistema de correo y de encolado.

De hecho, creo que esa demostración es impresionante. Y quieres ver, mira esto, el código para todo eso está en un solo archivo y es, en realidad, no, eso es el playground. Vamos a ver la versión final. Esto incluye toda la interfaz de usuario optimista, haciendo que parezca que es increíblemente rápido incluso si estás en una conexión 3G. Son 600 líneas de código. Eso incluye el código frontend y backend. Eso no incluye la gestión de sesiones para la autenticación de usuarios. Son 90 líneas de código, y el modelo, en realidad, no, no tenía un modelo. Hablé directamente con la base de datos en este archivo. Así que sí, es prácticamente como si estuvieras, si sumaras todas las líneas de código de todo junto, serían menos de 1,000 líneas, lo cual me parece gracioso porque es mucho menos que muchos de los MVC reales donde todo era solo interfaz de usuario, frontend, almacenamiento local, sin autenticación de usuarios, sin manejo de condiciones de carrera, sin persistencia real, nada de eso. Así que podemos hacer más con mucho menos, y además, porque gran parte de esto sucede en el backend, tampoco tenemos que enviar tanto JavaScript al frontend. Y así también se carga mucho más rápido, lo cual es genial. Así que cosas increíbles que puedes hacer cuando tienes un servidor.

Si vamos a Remix Runs stacks, esto es lo que estás buscando. Stacks es una característica realmente genial donde puedes crear tus propios andamios personalizados, pero tenemos tres oficiales que vienen preconfigurados con un montón de herramientas como ESLint, Prettier, BTest, TypeScript, Testing Library, MSW, Cypress, Tailwind, Prisma, todas las cosas que tiene. Autenticación de usuarios incorporada e instrucciones para implementar en fly. Todo está preconfigurado. El stack Grunge se implementará en AWS Lambda. Sí, es realmente impresionante. Así que eso es lo que recomendaría, investigar Stacks. Y lo que es realmente genial es que la comunidad ha participado y si buscas la etiqueta Remix Stack en GitHub, encontrarás un montón de ellos. Hay 54, creo, stacks diferentes que la gente ha creado. Es más grande que solo nosotros. Esperamos que la mayoría de las personas realmente construyan uno de estos para su empresa. Y luego tu empresa simplemente puede, como cualquier proyecto que necesites, crear un nuevo proyecto que ya tenga tu biblioteca de componentes instalada y configurada y todas esas cosas también. Así que echa un vistazo a Stacks.

Oh, la aplicación de tareas pendientes. Permíteme mostrarte dónde está esa aplicación de TODO MVC, es Remix TODO MVC. Sí, aquí está el código para eso. ¿Remix tiene una API para invalidar o borrar la caché del navegador para un punto final? Entonces, no hay una API. El navegador no proporciona una API para borrar la caché del navegador para nada. Pero si necesitas, en primer lugar, diré que si eso es una preocupación para ti por alguna razón, que podría haber un momento o una duración determinada en la que necesito que esta caché desaparezca, entonces no uses encabezados de caché para eso en su mayor parte. Sin embargo, puedes hacerlo. Simplemente agrega un parámetro de cadena de consulta adicional y ahora obtienes una nueva entrada en la caché. Es posible, pero generalmente no es el mejor enfoque para hacerlo. He descubierto que el almacenamiento en caché depende del caso de uso. Así que no queremos hablar tanto sobre el enfoque porque dependerá mucho del caso de uso. Entonces, sí, no hay una API para eso. No he encontrado una situación en la que necesitara tener cosas en caché en el cliente, pero puedes hacerlo si quieres, y también puedes usar completamente React Query con Remix si quieres. Simplemente no he encontrado una situación en la que sienta que eso sea útil. Y parece que Jonathan tenía una pregunta anteriormente. Lo siento, ¿tiene el equipo de Remix planes para expandirse más como un framework de pila completa al estilo de Rails? ¿Qué, quiero decir, hay más soporte incorporado para modelos de bases de datos y todas esas cosas? Sí, posiblemente. Creo que Remix ha resuelto la parte más difícil del desarrollo web, y esa es la parte central de la pila. El puente entre el cliente y el servidor. Esa siempre ha sido la parte más difícil. Rails está aquí tratando de lanzar ganchos con su hotwire o sus antiguos TurboLinks, todas las cosas que han estado intentando hacer. Y si alguien ha usado hey.com para su cliente de correo electrónico, saben que eso simplemente no funciona muy bien. Y luego Laravel tiene muchos de los mismos problemas. Pierdo la cuenta, y Phoenix con su vista en vivo. Y Laravel tiene su algo más en vivo. Todos ellos, live wire creo que es lo que es. Así que todos ellos simplemente están lanzando ganchos desde el servidor. Y luego Next está aquí en el otro lado y Gatsby y todos estos otros lanzando ganchos a funciones sin servidor o lo que sea, rutas de API y cosas al servidor. Y así, eso es como este abismo de red es la parte más difícil de todo. Y Remix acaba de solidificar eso, simplemente lo ha resuelto. Es como un puente sólido a través de ese abismo. En realidad, ni siquiera se siente como un puente. Es más como un dispositivo de teletransportación porque simplemente estás allí instantáneamente. Y no tienes que pensarlo. Así que eso, creo que es la parte más difícil. Y en cuanto a absorber los otros lados de la pila, como ir más allá del centro. Creo que es totalmente posible. La cosa es que en el ecosistema de JavaScript, ya tenemos algunas herramientas excelentes para el acceso a bases de datos. Como Prisma es increíble. Así que no estoy seguro de cuánto valor tendría para nosotros construir nuestro propio ORM. Probablemente solo envolveríamos Prisma si acaso. Y en el lado del cliente, como comer el otro extremo de la pila, ya tenemos Reach UI, que también es parte de Remix. Y probablemente construiremos más sobre eso en el futuro y crearemos un Reach UI que tenga conocimiento sobre el backend. Así que tenga algún conocimiento sobre el backend también. Y sí, podríamos construir un sistema de correo y un sistema de encolado o algo así, no sé.

Financiamiento de Remix y Estilo CSS

Short description:

Remix tiene planes para generar ingresos a través de servicios relacionados con Remix o mediante la creación de un producto. También tienen la opción de ser adquiridos. Actualmente, cuentan con suficiente financiamiento para al menos uno o dos años. Remix ofrece flexibilidad en la carga de CSS para rutas y componentes específicos, lo que permite un estilo independiente. Admite archivos CSS individuales para cada ruta, evitando los problemas de la Cascada. Se recomienda Tailwind para estilizar aplicaciones con Remix. Los módulos CSS y Vanilla Extract no son compatibles actualmente, pero hay planes para agregar soporte en el futuro. Se desaconseja el uso de CSS-in-JS a favor de Tailwind. El único tipo de TS obsoleto en Remix es el genérico no utilizado para useLoaderData.

Entonces, los stacks son lo que hemos creado porque aún no tenemos esas cosas. Eventualmente, las cosas que están incorporadas en estos pueden ser incorporadas en Remix en el futuro. Pero sí, por ahora los stacks son un buen punto de partida. Genial.

Y hubo otra pregunta que me perdí acerca de Remix siendo de código abierto. ¿Cómo genera ingresos? Tenemos muchas ideas sobre cómo generar ingresos con Remix o con servicios relacionados con Remix, algo así como lo que hace Laravel, o podríamos crear un producto, algo así como lo que hace Rails con Basecamp, o podríamos ser adquiridos. Siempre está esa opción. Así que si trabajas en una gran empresa como Microsoft o algo así, avísame. Eso sería genial. Entonces no tendríamos que preocuparnos por generar ingresos. Alguien más pagaría las cuentas. Pero sí, tenemos al menos un año, tal vez dos, de financiamiento, solo con nuestra ronda inicial de financiamiento. Y cuando lleguemos a nuestra Serie A, obtendremos aún más. Así que no estoy muy preocupado por eso. Nuestros inversores de capital de riesgo nos dicen que no nos preocupemos por generar ingresos en este momento. Solo preocupémonos por conseguir usuarios. Eso es en lo que estamos enfocados. Pero sí, eso es todo.

Ok, ¿cuáles son las otras opciones y estrategias para cargar CSS para una ruta de página y un componente específico? Para una ruta, no entramos en eso en este taller, pero sí lo hago en la aplicación TodoMVC. Tengo este archivo todos.css. Así que es solo un archivo CSS regular, pero notarás que si vas a Remix TodoMVC, en realidad te lleva a la página de inicio de sesión. Aquí no hay ningún CSS. Porque aquí tenemos el cuerpo HTML con margen cero y todos los botones deben verse así. Básicamente, copié y pegué esto y luego lo modifiqué ligeramente desde el TodoMVC original. Pero no quería que el CSS afectara a las otras páginas. Como la página de inicio de sesión. Quería que esta tuviera Tailwind porque no quería tener que escribir ningún CSS. Y así es como podemos manejar eso. En el archivo todo.tsx, importamos ese archivo CSS y obtenemos una URL para la hoja de estilos. Y luego exportamos los enlaces. Estos son los enlaces que deben estar en la página cuando esta ruta está activa y tendrá esa hoja de estilos de tareas pendientes. Bueno, cuando no estoy en esta página, esos enlaces no estarán allí. Y por eso no tenemos ninguno de esos estilos en esta página porque no estoy en esa ruta. Entonces, si miramos el HTML, no veremos ese margen o relleno cero, lo que sea. Esto se debe a que Remix nos brinda esa API para determinar qué enlaces deben estar en la página. Entonces, cuando estoy en la página de inicio de sesión, veo este Tailwind CSS, y eso es porque si voy a la página de inicio de sesión, tengo este archivo CSS de Tailwind aquí, pero no quiero Tailwind en la página de TodoMVC porque eso afectaría los estilos de TodoMVC. ¿Tengo eso en la página de tareas pendientes? Mira Remix TodoMVC. Entonces, cuando estoy en esta página, Tailwind arruina esos estilos. Y verás que tengo el enlace rel hoja de estilos para el CSS de tareas pendientes, pero no para Tailwind. Así que todo eso para decir que Remix hace que la Cascada sea increíble. Hemos recuperado la Cascada y no tiene ninguno de los enormes inconvenientes que siempre tuvimos con la Cascada. La forma en que construirías CSS a gran escala en cualquier empresa grande en la que trabajé era tener todos tus archivos CSS y luego Sass los combinaría en uno gigante que se colocaba en todas las páginas. Esa era la forma más fácil de hacerlo. De lo contrario, tenías que agregarlo a cada página y eso era súper molesto. Pero luego tenías problemas con la Cascada porque hacías un cambio aquí y cambiaba todo. Así que Remix lo hace realmente bien porque puedes asociar archivos CSS individuales a rutas individuales y son completamente independientes entre sí. Entonces, esa es una forma de estilizar aplicaciones con Remix. La otra es simplemente usar Tailwind. Eso es lo que hago y es increíble. Me encanta Tailwind, pero sé que no a todos les gusta o tal vez tienes una aplicación que estás migrando o algo así. Entonces, actualmente no admitimos módulos CSS o Vanilla Extract, pero tenemos planes realmente geniales para agregar el mejor tipo de soporte para esas cosas que puedas imaginar. Así que eso sucederá eventualmente. Pero sí, eso aún no sucede. Y luego, sí, en cuanto a CSS en JS, deberías dejar de usar eso. Es malo para tus usuarios. Es lento. Bueno, no es terrible, pero porque ahora tenemos estas otras opciones, estas cosas son mejores. Simplemente usa Tailwind. Eso es lo que digo. Entonces, eventualmente tendremos una mejor solución o mejor soporte para otras soluciones que no sean malas. Como los módulos CSS, en realidad son bastante buenos. Me gustan los módulos CSS bastante bien. Y Vanilla Extract también es muy interesante. Y esas cosas no son malas para tus usuarios. Están bien.

Ok, ¿y qué hay de los tipos de TS que están obsoletos, solo los genéricos no utilizados? Sí, ese es el único. Es ese genérico no utilizado. No uses el genérico useLoaderData. El genérico JSON está bien. Es solo el useLoaderData. Siempre tendremos algo mejor al que migrar y siempre te daremos tiempo para hacerlo. Así que no te preocupes por eso.

Desafíos y el Administrador de Transiciones

Short description:

El administrador de transiciones en Remix es un desafío importante y un componente clave que maneja las solicitudes de cancelación, reenvío y lógica de revalidación. Es una característica compleja y bien probada que permite transiciones suaves y una recuperación eficiente de datos. Funciona como magia, cancelando solicitudes innecesarias y proporcionando la respuesta deseada. El administrador de transiciones es una parte crucial de la funcionalidad de Remix.

De acuerdo, ¿cuál es el desafío más grande, el problema más difícil de resolver al construir Remix con el propio framework? No lo sé. Para ser honesto, estoy involucrado en sesiones de design con Ryan y Michael y nuestros otros ingenieros cuando hablamos sobre nuevas APIs y cosas así. Así que estoy involucrado en esa fase. Pero en cuanto al desarrollo real, he hecho muy poco en la construcción de Remix. Así que no sé si soy la mejor persona para responder esa pregunta.

En realidad, sabes qué, probablemente el administrador de transiciones. Ryan y yo pasamos mucho tiempo hablando de eso. Y el administrador de transiciones es el que hace que pueda hacer esto, lento 3G. Y luego puedo venir aquí y hacer esto, eliminar y boom, boom, boom, boom, boom, boom, boom. Ver todas esas solicitudes de cancelación y cosas así. Y si alguna de estas tiene, si hay un reenvío o algo así, envío múltiple mientras todas están en proceso o algo así. Toda la lógica que rodea qué solicitud cancelar, cuál de ellas, cuándo volver a validar, toda esa lógica es bastante complicada. Y funciona muy bien. Es muy bien probada. Estuve involucrado en eso. Así que ahí lo tienes. Todo ha desaparecido, como por arte de magia. Ah, es tan genial. Sí, ves, y cancelamos todas esas porque no las necesitamos. Obtenemos todos los data que necesitamos de esta. ¡Ta-da! Aquí está la respuesta. No quedan tareas pendientes. Entonces, ¿por qué necesitamos esas? No las necesitamos. Tan genial. De acuerdo, parece que hemos terminado.

Watch more workshops on topic

React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Featured WorkshopFree
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)
Remix Conf Europe 2022Remix Conf Europe 2022
195 min
How to Solve Real-World Problems with Remix
Featured Workshop
- Errors? How to render and log your server and client errorsa - When to return errors vs throwb - Setup logging service like Sentry, LogRocket, and Bugsnag- Forms? How to validate and handle multi-page formsa - Use zod to validate form data in your actionb - Step through multi-page forms without losing data- Stuck? How to patch bugs or missing features in Remix so you can move ona - Use patch-package to quickly fix your Remix installb - Show tool for managing multiple patches and cherry-pick open PRs- Users? How to handle multi-tenant apps with Prismaa - Determine tenant by host or by userb - Multiple database or single database/multiple schemasc - Ensures tenant data always separate from others

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2021React Advanced Conference 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Humans are natural problem solvers and we're good enough at it that we've survived over the centuries and become the dominant species of the planet. Because we're so good at it, we sometimes become problem seekers too–looking for problems we can solve. Those who most successfully accomplish their goals are the problem eliminators. Let's talk about the distinction between solving and eliminating problems with examples from inside and outside the coding world.
Remix Conf Europe 2022Remix Conf Europe 2022
23 min
Scaling Up with Remix and Micro Frontends
Top Content
Do you have a large product built by many teams? Are you struggling to release often? Did your frontend turn into a massive unmaintainable monolith? If, like me, you’ve answered yes to any of those questions, this talk is for you! I’ll show you exactly how you can build a micro frontend architecture with Remix to solve those challenges.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai
React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.