Video Summary and Transcription
Se discute la gestión del estado global y los desafíos de colocar el estado del servidor en el estado global. Se introduce React Query como una solución para manejar el estado del servidor asíncrono. La charla demuestra el proceso de extraer la lógica en hooks personalizados y solucionar problemas con la lógica de estado y de búsqueda. Se muestran las actualizaciones optimistas con mutación, junto con los beneficios de usar React Query para la búsqueda de datos y las mutaciones. Se discute el futuro de la gestión del estado global, junto con los comentarios de los usuarios sobre React Query. La charla concluye con una invitación para explorar React Query para la gestión del estado del servidor.
1. Introducción a la Gestión del Estado Global
Hola, soy Tanner Linsley, cofundador y vicepresidente de UI y UX en nozzle.io. Hoy, quiero hablar sobre la gestión del estado global y el error de colocar el estado del servidor en el estado global. El estado del servidor es diferente del estado del cliente en términos de almacenamiento, velocidad de acceso y propiedad. Vamos a explorar por qué y cómo podemos manejar el estado del servidor de manera más efectiva.
Hola a todos. Mi nombre es Tanner Linsley, y soy cofundador y vicepresidente de UI y UX en nozzle.io, donde construimos software de seguimiento de rango SEO para enterprise. Me encanta absolutamente React y JavaScript, y tengo un poco de obsesión por construir software de código abierto también.
Así que desde que aprendí React, he estado súper obsesionado con temas como la generación de sitios estáticos, data visualization, y animation. Pero hoy me gustaría hablarles sobre lo que posiblemente es mi favorito de todos, la gestión del estado global.
Hoy en día, una tonelada de code en nuestras aplicaciones está dedicada a consumir y manipular datos asíncronos. Ya sea que esos datos provengan de nuestros usuarios o servidores o APIs de terceros, es absolutamente crítico para nuestras aplicaciones proporcionar valor a nuestros usuarios. De hecho, para muchos de nosotros, nuestras aplicaciones son simplemente interfaces de usuario con opiniones para consumir y gestionar estos datos.
A lo largo de los años, he notado que los patrones alrededor del acceso y manipulación de nuestros datos en nuestras aplicaciones han tomado rápidamente residencia con lo que todos conocemos como estado global. El estado global es súper conveniente. Nos ayuda a evitar la perforación de propiedades, y nos permite acceder a los datos a través de nuestra aplicación sin copiarlos o duplicarlos. E incluso nos ayuda a comunicarnos entre componentes y hooks aislados que de otra manera no podrían hacerlo. Al final, simplemente nos ayuda a hacer más con menos code. Es extremadamente accesible y poderoso, por lo que es natural que querríamos que todos nuestros importantes datos del lado del servidor fueran tan accesibles como nuestro estado global. Y con esa expectativa, no es sorprendente que nosotros, como desarrolladores de React, hayamos elegido co-ubicar nuestros datos del lado del servidor con el resto de nuestro estado global.
Es relativamente fácil hacer esto usando algo como el estado del componente local con el contexto de React, o incluso usando cualquiera de las numerosas bibliotecas de la siempre creciente lista de herramientas de gestión del estado global. Pero al final, la expectativa suele ser la misma. Esperamos que nuestro estado global no sólo sea capaz de manejar cosas triviales como el estado del menú, temas, cosas como toasts y alertas, sino que también esperamos que sea responsable de los ciclos de vida complejos alrededor de la obtención y provisión de nuestros datos del lado del servidor y asíncronos a nuestros usuarios.
Así que hoy, estoy aquí para decirles que a pesar de la conveniencia efímera que nos da el estado global al trabajar con datos del lado del servidor, creo que hemos cometido un gran error al colocarlo allí. Nos hemos engañado a nosotros mismos y a nuestro code pensando que todo el estado es creado igual, cuando creo que nuestros datos asíncronos y el estado global no podrían ser más diferentes, especialmente cuando se trata de dónde se almacenan, la velocidad a la que los accedemos, y cómo los accedemos y actualizamos, y finalmente quién puede hacer cambios en ellos.
Para hacer todo esto más fácil de entender, quiero dejar de usar el término estado global y en su lugar llamar a estos dos tipos diferentes de estado estado del cliente y estado del servidor. El estado del cliente es relativamente simple y debería ser familiar para la mayoría de los desarrolladores. Es temporal y local, y generalmente no se persiste entre sesiones. Se accede a él con APIs sincrónicas que no tienen latencia, y la mayoría de él es propiedad de la instancia de nuestra aplicación cliente. Así que por todas esas razones, podemos confiar bastante en que nuestro estado del cliente siempre estará al día en cualquier momento en nuestra aplicación.
Sin embargo, el estado del servidor es bastante diferente. El estado del servidor se persiste de forma remota, por lo que la fuente de la verdad de nuestro estado del servidor es potencialmente desconocida, o al menos fuera de nuestro control. Es asíncrono, por lo que tenemos que acceder a él con APIs asíncronas, y también tiene una propiedad compartida implícita, lo que significa que no sólo es propiedad de nuestro cliente. Puede ser leído y manipulado tanto por el servidor como por cualquier otro cliente potencial que interactúe con él. Debido a todas estas cosas, se pueden hacer muy pocas garantías sobre nuestro estado del servidor siempre estando al día en nuestras aplicaciones, y en su lugar generalmente terminamos confiando en simples instantáneas de nuestros datos asíncronos.
2. Estado del Servidor y Estado del Cliente
Cuando el estado del servidor y el estado del cliente se almacenan en el mismo sistema, se hacen concesiones. El estado del servidor tiene desafíos únicos que requieren herramientas dedicadas. React Query es una biblioteca NPM que resuelve el estado del servidor asíncrono con una API pequeña y simple. Para demostrar sus capacidades, construí una aplicación de blog con React y Next.js. La aplicación permite ver, editar y agregar publicaciones. Inicialmente, la aplicación tenía cuatro componentes principales, cada uno utilizando useEffect y React State para la obtención de datos y los estados de carga. Sin embargo, quería hacer el código más portátil.
Entonces, cuando tomamos estos dos tipos muy diferentes de estado, el estado del servidor y el estado del cliente, y intentamos almacenarlos en el mismo sistema, eventualmente haremos concesiones que favorecen a uno o al otro. Un buen ejemplo de esto es que el estado del servidor tiene sus propios desafíos únicos que nunca enfrentamos con el estado del cliente. Por ejemplo, algunos de estos podrían ser cosas como el almacenamiento en caché, la desduplicación de solicitudes, la actualización de data en segundo plano, lidiar con solicitudes obsoletas, lidiar con mutaciones, paginación y obtención incremental, o incluso la recolección de basura, la gestión de errores de memoria y todo lo demás que viene con el almacenamiento en caché en general. Muchos patterns de estado global no ofrecen soluciones para este tipo de desafíos, o al menos intentan resolverlos con APIs complicadas o sistemas de plugins sobreingenierados, y a veces incluso APIs sobre potenciadas que son básicamente armas de fuego para el desarrollador promedio de React.
El estado del servidor y el estado del cliente claramente necesitan mucho amor, pero cada uno lo necesita a su manera. Y aunque creo que tienen algunas cosas en común en cuanto a cómo los accedemos en nuestras aplicaciones, creo que es hora de que el estado del servidor y el estado del cliente se separen. Hay mucho más en el estado del servidor que simplemente ser accesible globalmente, y creo que se merece nuevas herramientas dedicadas que no solo resuelvan estos desafíos, sino que los manejen automáticamente de una manera elegante. Esta es exactamente la razón por la que decidí construir React Query. React Query es una biblioteca NPM compuesta por un par de hooks y utilidades que buscan resolver el estado del servidor asíncrono. Es una API pequeña, es simple, y está diseñada para ayudar tanto a los desarrolladores novatos como a los advanced de React a tener éxito mientras requiere poca o ninguna configuración.
Para realmente saber cómo React Query puede transformar drásticamente la forma en que manejas el estado del servidor, decidí construir una pequeña aplicación de blog interactiva usando React y una pequeña API alimentada por Next.js. Entonces, el propósito de esta aplicación es bastante simple. Es mostrar una lista de publicaciones, nos permite ver una vista detallada de una publicación individual, y luego nos permite editar publicaciones existentes o agregar nuevas. Voy a navegar a través de algunas etapas o commits que hice en este proyecto de cómo evolucionó la gestión del estado de esta aplicación en la naturaleza y cómo, al final, finalmente llegué a usar React Query para salvar el día.
Entonces, primero, familiaricémonos con la aplicación. Tenemos una barra lateral confiable con un solo enlace a nuestra página de publicaciones. Tenemos una página de publicaciones que obtiene todas nuestras publicaciones de nuestra API y las muestra en una lista. Podemos hacer clic en una publicación y cargar la vista detallada con el contenido completo. Podemos usar el formulario de edición en la parte inferior para editar la publicación. Y luego, de vuelta en nuestra lista de publicaciones, podemos usar ese mismo formulario para agregar una nueva publicación a la lista. Entonces, para hacer todo esto, nuestra aplicación comenzó con cuatro componentes principales. Un componente de aplicación, que maneja todas nuestras rutas y el estado de las rutas. Un componente de publicación, que obtiene nuestras publicaciones de la API y luego las muestra con el formulario para agregar nuevas publicaciones debajo de ellas. Un componente de publicación individual que obtiene el contenido completo de una publicación y lo renderiza y luego nos da el formulario de edición en la parte inferior. Y finalmente, tenemos un componente de formulario de publicación reutilizable que simplemente es para editar los campos de la publicación. Entonces, en cada uno de estos componentes de publicación, ahora mismo estamos usando una estrategia de use effect para llamar a una función asíncrona y obtener nuestros data. Y luego usamos el Estado de React para seguir el estado de carga de esas solicitudes. De esta manera, cuando montamos cada uno de esos componentes, los data se solicitan y eventualmente se renderizan en nuestra UI. Y todo esto está bien y funciona, pero personalmente no me gusta tener mucha lógica de negocio en mis componentes. Así que quiero ver si podemos hacer esto un poco más portátil.
3. Extrayendo Lógica en Hooks Personalizados
En el siguiente commit, he extraído la lógica para obtener datos en hooks personalizados. Esto nos permite reutilizar los hooks en toda nuestra aplicación. Sin embargo, estamos experimentando un problema donde el endpoint de la publicación se llama dos veces. Esto se debe a que cada vez que usamos el hook, se crea una nueva instancia de estado y efectos, lo que resulta en solicitudes duplicadas de datos.
En este siguiente commit, he extraído toda la lógica para obtener nuestros data y los he puesto en sus propios hooks personalizados. Así que los archivos use posts y use post ahora contienen toda la misma lógica y estado para obtener nuestras listas de publicaciones y detalles de publicación, pero solo combinados en un hook personalizado. Y luego también he movido toda la lógica para nuestras mutaciones en algunos archivos nuevos llamados use create post y use save post que funcionan de manera similar. Así que esto libera a nuestros componentes de la necesidad de definir toda la lógica ellos mismos y solo se centran en renderizar la UI, que en mi opinión es un gran patrón independientemente de cómo manejes tu estado.
Así que ahora que tenemos nuestra lógica de obtención dentro de estos hooks reutilizables, podemos usarlos de nuevo en cualquier otro lugar de nuestra aplicación que queramos. También en este commit, agregué un pequeño contador total de publicaciones en nuestra barra lateral que llama al mismo hook use posts de nuevo para mostrar un recuento total de publicaciones. Así que con toda esta abstracción, podría parecer una gran victoria para la reutilización de code. Pero si miramos nuestra pestaña de red, vamos a ver que algo extraño está sucediendo. Nuestro endpoint de publicación se está llamando dos veces, una vez para la lista de publicaciones y otra vez para el contador total de publicaciones. Aunque no hemos extraído el estado en, aunque hemos extraído el estado en hooks reutilizables, no significa realmente que los data dentro de ellos sean en sí mismos reutilizables. La verdadera razón por la que esto está sucediendo en realidad es porque cada vez que usamos nuestro hook use posts estamos creando una nueva instancia de estado y efectos cada vez que lo renderizamos. Así que si seguimos así, vamos a estar solicitando doblemente una tonelada de data para nuestra aplicación una y otra vez cada vez que usemos ese hook.
4. Corrigiendo el Estado y la Lógica de Obtención
En el próximo commit, mostraré cómo solucionar el problema convirtiendo el estado y la lógica de obtención en nuestros hooks en componentes globales que se renderizan una vez para toda la aplicación. Al crear un componente raíz para la lista de publicaciones y mover la lógica de obtención allí, podemos tener un solo lugar para obtener la lista de publicaciones. Usaremos un objeto de contexto para pasar el estado y la lógica a través del árbol de componentes, permitiendo que nuestro hook use posts acceda a la lista global de publicaciones. Veamos si esto resuelve nuestro problema.
En este próximo commit, voy a mostrar cómo intento solucionar eso convirtiendo parte del estado y la lógica de obtención en nuestros hooks en componentes globales que solo se renderizan una vez para toda la aplicación. Así que he creado un componente raíz para nuestra lista de publicaciones y he movido toda la lógica de obtención a ese componente. De esta manera, tenemos un solo lugar donde puede ocurrir la obtención de nuestra lista de publicaciones para toda nuestra aplicación, siempre y cuando lo rendericemos en la raíz y solo lo rendericemos una vez. Como solo podemos renderizarlo una vez, tenemos que tomar todo ese estado y lógica y enviar a través de nuestro árbol de componentes React a través de un objeto de contexto. De esta manera, en nuestro hook use posts, podemos suscribirnos a ese contexto y obtener acceso a nuestra lista global de publicaciones para nuestra aplicación. Así que vamos a ver si eso resolvió nuestro problema.
5. Corrigiendo las Solicitudes Dobles
Nuestro endpoint de publicaciones todavía está siendo solicitado dos veces debido al hook use posts que obtiene datos para cada instancia. Para solucionar esto, utilizamos un ref de React para rastrear promesas y reutilizar la promesa de la solicitud original para las solicitudes posteriores. Esto asegura que se haga una única solicitud, y los componentos se cargan simultáneamente.
No, no lo hizo. Parece que nuestro endpoint de publicaciones todavía está siendo solicitado dos veces. Esto puede parecer extraño, pero en realidad es porque cada vez que cargamos nuestro hook use posts, necesitamos asegurarnos de que está obteniendo los data para que estén actualizados para el componente que va a usarlo. Pero esto también significa que cada instancia va a llamar a la función fetch cada vez que se monta, incluso si se montan al mismo tiempo. Afortunadamente, conozco una forma de solucionar esto, y necesitábamos el estado global de todos modos, así que al menos no perdimos nuestro tiempo con eso.
En el próximo commit, voy a mostrarles la forma más fácil que conozco para eliminar las solicitudes asíncronas que ocurren al mismo tiempo. Así que empezamos utilizando un ref de React para rastrear la promesa de cualquier solicitud saliente. Luego, si hay alguna otra solicitud que ocurra mientras la promesa aún está pendiente, simplemente podemos reutilizar la promesa de la solicitud original para que no disparemos ninguna extra, y cada función asíncrona todavía puede resolverse cuando la solicitud original regresa. Y si volvemos a nuestro panel de red ahora, puedes ver que solo hay una única solicitud para nuestro endpoint de publicaciones, y tanto nuestra lista de publicaciones como el contador total de publicaciones terminan cargándose al mismo tiempo, lo cual es súper genial.
6. Añadiendo Búsqueda de Publicaciones y Estado de Publicación Individual
En este próximo commit, he añadido un cuadro de búsqueda en la barra lateral para buscar publicaciones por ID. El estado de detalle de la publicación ahora almacena estados separados para cada detalle, incluyendo estado, datos, error y referencia de promesa. Esto permite que tanto la vista de detalle como la barra lateral se actualicen simultáneamente y compartan la misma solicitud.
Hasta este punto, hemos estado prestando mucha atención a nuestra lista de publicaciones. Cambiemos de marcha y revisemos nuestra vista de publicación individual. Es genial que podamos hacer clic en una publicación para ver su contenido, pero sabía que eventualmente iba a necesitar una forma de buscar una publicación por su ID, lo cual no puedo hacer con esta UI aún. Así que en este próximo commit, he añadido un pequeño cuadro de búsqueda en mi barra lateral que me permite introducir un ID de publicación y consultar mi API para ello. Simplemente vamos a coger un ID de una de estas publicaciones, lo ponemos aquí en el cuadro de búsqueda. Si se encuentra la publicación, muestra el título y me permite hacer clic en él para abrir la publicación, lo cual es súper genial. Pero poco después de añadir esta característica, noté que otra cosa extraña sucedía cuando yo editaría una publicación que también tenía cargada en la barra lateral.
Así que si editamos esta publicación, el detalle de la publicación se recarga con el título correcto, pero la barra lateral se queda atascada con el antiguo. Y la forma en que nuestra aplicación está estructurada en este momento, realmente no hay una buena forma de forzar a esa barra lateral a recargarse sin introducir más estado global. Fue bastante fácil convertir nuestra lista de publicaciones en estado global, así que pensé que no debería ser mucho más difícil hacerlo con el estado de la publicación individual también. Y luego en este próximo commit, te mostraré algunas cosas difíciles con las que me encontré cuando, sabes, que no tuve que preocuparme en el estado de la lista de publicaciones, pero cómo las superé. Así que lo que sucedió aquí es que nuestro estado de detalle de publicación en realidad necesitaba almacenar un estado separado para cada detalle diferente que estábamos solicitando al servidor, incluyendo estado, data, error, e incluso su propia pequeña referencia de promesa para que pudiéramos rastrear y deduplicar promesas a nivel de detalle de publicación individual. Fue un poco más de trabajo, pero salió bien. Y funciona tan bien como nuestro estado global de lista de publicaciones. Y puedes ver ahora si cogemos un ID de publicación, lo buscamos en nuestra barra lateral, intentamos actualizar el título, tanto la vista de detalle como la de la barra lateral se actualizarán e incluso compartirán la misma solicitud. Así que esto es definitivamente más consistente que lo que teníamos antes.
7. Mejorando la Obtención de Datos y Mutaciones
A pesar de que hemos avanzado con el estado global, todavía hay problemas con los estados de carga. React Query resuelve estos problemas al manejar el almacenamiento en caché y la nueva búsqueda en segundo plano. Simplifica la obtención de datos y reduce el código. Las mutaciones, como agregar y editar publicaciones, ya no desencadenan estados de carga innecesarios.
Y aunque sentí que, supongo que hasta este punto, hemos logrado bastante con la adición de estado global y todo eso, todavía hay un par de problemas en este punto que todavía me molestan. En primer lugar, creo que se muestran demasiados estados de carga. Y honestamente, después de todo el duro trabajo que acabamos de hacer con el estado global, fue un poco decepcionante que todos los estados de carga todavía estuvieran ocurriendo.
Otra cosa es que cuando activamos una búsqueda para una de nuestras publicaciones, como con la barra lateral de búsqueda, mientras también miramos la misma publicación en la vista de detalle, la vista de detalle se pone en un estado de carga también cuando realmente no necesita hacerlo. Y honestamente, se siente como una mala user experience. Y luego las otras cosas que aún no hemos mirado son cosas como el almacenamiento en caché, la paginación, y realmente no quiero pensar en cómo podríamos acceder de forma sincrónica a nuestro estado global en este momento para hacer actualizaciones optimistas en nuestras mutaciones. Así que podríamos seguir en este agujero de conejo loco tratando de doblegar el estado global a nuestra voluntad y manejar todos estos casos límite. Pero puedes tomar mi palabra de que se complica bastante rápidamente. Incluso para los gestores de estado global más advanced, se vuelve bastante loco.
Y con eso dicho, finalmente creo que es hora de que React Query entre en acción y salve el día. Así que en este próximo commit, he movido todos nuestros hooks de obtención de data para usar React Query en lugar de nuestro estado global y la lógica de use effect. Y como puedes ver, pudimos eliminar unas 150 líneas de code de nuestros hooks de publicación y también de nuestros hooks de publicación y reemplazarlos con unas pocas líneas del hook de uso de mutación de React Query, o no, hook de uso de consulta. Todo lo que tuvimos que hacer fue obtener una clave única para nuestros data y la función asíncrona para ir a buscarla. Así que veamos cómo funciona eso.
Muy bien. Definitivamente está funcionando. Y honestamente, se siente mucho más rápido a medida que nos movemos por la aplicación, especialmente para las vistas y las publicaciones que ya hemos visitado. Y esto es principalmente porque React Query maneja automáticamente el almacenamiento en caché y la nueva búsqueda en segundo plano directamente de la caja. Y cuando las cosas están en caché, pueden ser renderizadas inmediatamente la próxima vez que se vean. Y honestamente, a veces puede sentirse un poco irreal, como cuando buscamos una publicación en nuestra barra lateral y hacemos clic en el enlace. Dado que la publicación ya está en caché desde la búsqueda en la barra lateral, la vista de detalle se carga instantáneamente. E incluso notarás un pequeño estado de actualización en la parte superior que nos dice que estaba siendo buscado y recargado en segundo plano, a pesar de que se recargó inmediatamente.
Así que todo esto es súper genial. La obtención de data está funcionando mucho mejor, y pudimos eliminar un montón de code. Ahora quiero ver cómo están funcionando nuestras mutaciones y cómo se sienten. Así que agregar una publicación es mucho mejor ahora porque no entra en el estado de carga para buscar la nueva publicación. Y ni siquiera, bueno, y simplemente se vuelve a buscar en segundo plano y se añade al final de la lista. Así que no obtenemos ese estado de carga desconcertante que teníamos antes. Y lo mismo con la edición de una publicación. Ya no veremos ese estado de carga tampoco.
8. Actualizaciones Optimistas con Mutación
En este próximo commit, voy a mostrar cómo usar la mutación para hacer algo llamado actualizaciones optimistas. Son una excelente manera de hacer que su interfaz de usuario se sienta rápida, incluso cuando se trabaja con datos asíncronos. Al usar los callbacks de on mutation y on error, junto con el caché de consultas de React Query, podemos actualizar de manera optimista nuestra interfaz de usuario y volver a un valor anterior si la mutación falla. Si tiene éxito, activamos una nueva búsqueda en segundo plano para asegurarnos de que estamos viendo el estado del servidor real. Observa de cerca cómo uso el formulario de anuncio de publicación para ver esto en acción. Nuestra aplicación es ahora impresionante.
Solo verás una actualización en segundo plano y aparecerá un nuevo título. Así que incluso con este nuevo botón que agregué para eliminar una publicación, incluso nos lleva de vuelta a la publicación página sin mostrarnos un estado de carga y simplemente activa una actualización en segundo plano, lo cual es genial. Quiero decir, honestamente, todo esto es realmente impresionante considerando que en este momento nuestras mutaciones son todavía realmente ingenuas.
De hecho, cuando disparamos nuestras mutaciones en nuestros componentes de UI en este momento, todavía estamos teniendo que asegurarnos de que llamamos a la función refetch para cualquier consulta que necesitemos actualizar en segundo plano. Y aunque eso funciona, hay una forma mucho más fácil de hacerlo que voy a mostrar en este próximo commit. Y en este próximo, este próximo commit, migro todos nuestros hooks de mutación a React Query también. Y la forma en que hacemos eso es con el hook use mutation. Y el hook use mutation nos ayuda a eliminar, de nuevo, nos ayuda a eliminar una tonelada de code que estaba dedicado a manejar nuestro estado de mutación y simplemente lo reemplaza con una sola llamada a use mutation. Y luego podemos pasar nuestra función de mutación asíncrona a eso. Y aunque todo lo que hicimos fue deshacernos de un montón de code, estaría contento con eso. Pero use mutation tiene un par de opciones más que nos ayudan a hacer mucho más.
La más obvia que puedes ver aquí es on success, que es solo una función que he pasado que se llama cada vez que nuestra mutación tiene éxito. Así que dentro de ese callback, podemos usar la otra importación de React Query llamada el caché de consultas para notificar a cualquier consulta relacionada que necesitan ser refetched. Y dado que estamos haciendo eso allí, toda la lógica de refetching en nuestros componentes es ahora se ha ido. Y podemos definir de manera declarativa nuestras dependencias de mutación una a la vez dentro de nuestra mutación en lugar de tener que llamar manualmente a todas las consultas para refetch cada vez que ejecutamos una mutación en nuestros componentes de UI. Y hasta este punto, estas cosas realmente no han hecho nada diferente para nuestra UI aparte de hacer el code más mantenible. Y al final del día, todavía estamos lidiando con un servidor que tarda un segundo o dos en aplicar nuestros cambios y devolvernos que necesitamos refetch. Para mí, y probablemente para todos ustedes también, esos pocos segundos pueden sentirse como una eternidad.
Entonces digo, ¿qué pasaría si pudiéramos predecir el futuro? ¿Qué pasaría si pudiéramos configurar nuestro estado para que muestre lo que esperamos que muestre después de que el servidor haya terminado, pero solo hacerlo de inmediato? En este próximo commit, voy a mostrar rápidamente cómo usar la mutación para hacer algo llamado actualizaciones optimistas. Son una forma realmente genial de hacer que tu UI se sienta realmente rápida, como si ni siquiera estuvieras trabajando con data asíncrona. Y use mutation tiene un par de opciones que podemos pasarle, como el callback de on mutation, que se ejecuta antes de que se ejecute nuestra función de mutación. El callback de on error, que se llama cuando nuestra función de mutación falla. Y si combinamos todos esos con las consultas de React, el caché de consultas y su capacidad para leer y escribir data de nuestro caché de manera sincrónica, podemos actualizar de manera optimista nuestra UI. Y luego, en el caso de que la mutación falle, podemos volver a un valor anterior. Y si tiene éxito, podemos activar una refetch en segundo plano para asegurarnos de que estamos viendo el estado del servidor real en lugar de solo una suposición. Así que si observas de cerca, mientras uso este formulario de anuncio de publicación aquí, verás que hace exactamente eso. Hay un 50-50 de posibilidades de que falle. Así que a veces tiene éxito y a veces falla. Pero puedes ver cómo nuestra UI mágicamente retrocede o se actualiza cada vez que ocurre cada escenario. Así que nuestra aplicación es ahora impresionante.
9. El Futuro de la Gestión del Estado Global
React Query es el futuro para manejar datos asíncronos y resolver desafíos con el estado del servidor. Nos ayuda a modelar y pensar sobre el estado global con una nueva perspectiva, y en algunos casos, lo elimina de nuestra aplicación.
Se siente genial. Es muy rápido. Y también es realmente mantenible. Pero todos ustedes vieron que cuando comenzamos esta aplicación, fue rápido y familiar saltar entre esos patrones comunes de UI en los que nos apoyamos cuando tratamos con el estado global. Y aunque podemos poner mucho trabajo duro en esos patrones de estado global, muchas cosas pueden salirse de control bastante rápido. Por eso, creo que herramientas como React Query son el futuro para manejar nuestros datos asíncronos. No solo resuelven los desafíos con el estado del servidor, sino que también nos ayudan a modelar y modelar globalmente nuestro estado global y pensar en nuestro estado global con una nueva perspectiva. Y en algunos casos, incluso lo elimina todo, o si no la mayoría de él, de nuestra aplicación.
10. Comentarios de los Usuarios sobre React Query
He recibido excelentes comentarios sobre React Query de los usuarios. Kent C. Dodds dijo que es la pieza que faltaba para el desarrollo de aplicaciones React. Marcelo Alves ama reemplazar Redux con React Query. Demetrius Clark encuentra que ayuda a mantener un flujo de trabajo productivo y la afinación de la interfaz de usuario. React Query es ahora su administrador de estado de servidor preferido.
He recibido muchos comentarios de personas que han usado React Query, y las personas tienen cosas geniales que decir al respecto. Me gustaría compartir rápidamente algunos divertidos con ustedes. Mi amigo Kent C. Dodds dijo que React Query es la pieza que faltaba para el desarrollo de aplicaciones React que he estado buscando después de años de construir aplicaciones React. Finalmente, tengo una herramienta que me da exactamente lo que necesito para resolver mis problemas de gestión de estado de aplicación sin darme más problemas. Es fantástico. Marcelo Alves dijo, todavía me gusta mucho Redux, pero cada vez que elimino una pieza de la tienda y la reemplazo con React Query, es una gran victoria. Y luego Demetrius Clark dijo, encontrar React Query me ha ayudado a mantener un flujo de trabajo extremadamente productivo dentro de React. Con consultas y mutaciones, mis componentes expresan claramente la intención, y finalmente puedo afinar la UI a un flujo que mis usuarios esperan debido a las poderosas estrategias de almacenamiento en caché. React Query es ahora mi administrador de estado de servidor preferido.
11. Conclusión e Invitación
Echa un vistazo a tu estado global y observa cuánto es estado del servidor y cuánto es estado del cliente. Al usar React Query para el estado del servidor, tendrás menos estado del cliente y una mejor experiencia de usuario. Sígueme en las redes sociales y echa un vistazo a mis otros proyectos y a mi startup, Nozzle.io. Gracias.
Así que, para cerrar el círculo, me gustaría dejar a todos con una invitación para que vayan y miren el estado global de sus aplicaciones y tomen nota de cuánto de él es estado del servidor y cuánto de él es estado del cliente. Creo que te vas a sorprender de cuánto de él está realmente fuera del control de tu aplicación y que al optar por manejar tu estado del servidor con una herramienta como React Query, de nuevo te sorprenderás de cuánto estado del cliente te queda realmente y de cuánto mejor será la experiencia de usuario de tu aplicación.
Así que gracias por escuchar y asegúrate de seguirme en Twitter, YouTube y GitHub. Y no olvides echar un vistazo a todos mis otros proyectos de código abierto y especialmente a mi startup, Nozzle.io. Gracias.
React Query y Comunicación con el Servidor
Estoy deseando probar React Query en mi propio proyecto. React Query puede soportar GraphQL con cualquier cliente GraphQL simple. Hay algo más genérico que Apollo para la comunicación con el servidor. Mientras sea transaccional y use promesas, funcionará. Para el estado del cliente restante, personalmente uso Context y un useReducer para una fácil gestión.
Debo decir, Tanner, eso fue impresionante. Muchas gracias por esta gran charla. De hecho, estoy deseando probar React Query en mi propio proyecto. También creo que no cobras por hora, ¿verdad? Claro, claro. No deberías hacer estas cosas si cobras por hora. Vamos, nos estás matando. Nos estás matando.
Quiero pasar directamente a las preguntas del público. Tenemos algunas y voy a empezar con la primera. ¿React Query también soporta GraphQL usando Apollo Client? Así que React Query puede soportar GraphQL, pero no lo hace a través de Apollo. Si quieres usar un simple cliente GraphQL para obtener datos, realmente puedes usar lo que quieras para obtener tus datos siempre y cuando devuelva una promesa y tus datos. Así que en realidad tengo mucha gente que está usando solo un simple cliente GraphQL y React Query juntos y dicen que les encanta. Así que hay muchas cosas geniales que pueden suceder allí. Genial, suena bien.
La siguiente pregunta es una especie de juego de eso. ¿Hay algo como Apollo, pero para formas más genéricas de comunicarse con el servidor que GraphQL? Sí, es una buena forma de ponerlo. Es más genérico. No está construido específicamente para GraphQL o realmente cualquier tipo de capa de datos específica o protocolo. Mientras sea basado en transacciones y use devoluciones de promesas, funcionará. Solo quieres promesas. Sí, no quiero promesas vacías. Necesito tus promesas. Muy bien, genial. Y luego tenemos otra pregunta de Ali. Él pregunta, para el pequeño estado del cliente restante, ¿usarías personalmente Redux o Context o cuál es tu forma preferida de hacer esto? Sí, en realidad, me quedó tan poco estado después de mover todo a React Query que terminé moviéndolo a algún Context. Uso un useReducer y uno o dos componentes de nivel base que proporcionan ese estado a través de Context al resto de mi aplicación. Y sinceramente, no he estado más feliz. Queda tan poco estado que es súper fácil de gestionar por tu cuenta. Mm-hmm. Vale.
React Query vs SWR
React Query y SWR logran cosas similares pero tienen APIs diferentes. React Query ofrece más flexibilidad en el almacenamiento en caché de consultas por claves y proporciona el hook useMutation para manejar los efectos secundarios de las mutaciones. SWR carece de este concepto. Estas diferencias me hacen preferir React Query.
Oh, y también, esa fue una buena pregunta para responder también sobre Redux. Tengo muchas personas que han cambiado a usar React Query para su obtención de data y todavía usan Redux para gestionar su verdadero estado de aplicación. Así que trabajan bien juntos. Pero no pueden vivir lado a lado en armonía. Mm-hmm.
Bueno. Pregunta de, bueno, Mai, no sé cuál es el nombre completo. Recientemente descubrí el sitio / SWR y parece genial. Es la primera vez que veo a React Query en acción y también parece realmente genial. Parecen lograr cosas similares. Si sabes, ¿podrías proporcionar algunas comparaciones y opiniones sobre los casos de uso que pueden ser adecuados para uno versus el otro? ¿O están prácticamente comparando manzanas con manzanas? Son muy similares en términos de lo que están tratando de lograr. Las APIs son diferentes simplemente porque no se desarrollaron en tandem. Cada uno tiene sus propias ideas sobre el diseño de APIs. Y en realidad tengo una lista de las diferencias muy menores y algunas diferencias realmente importantes en el read me de React Query. Hay un pequeño desplegable allí que dice ¿cómo es esto diferente de Zyte? Y puedes ir y mirar algunas de las cosas allí que son diferentes.
Una de las principales diferencias creo que es cómo se almacenan en caché las consultas por claves. La estructura de clave para React Query es un poco diferente y en mi opinión un poco más flexible para que puedas seleccionar qué consultas quieres volver a buscar y demás. Y también todo el concepto detrás de useMutation creo que es un hook realmente útil especialmente cuando empiezas a hacer cosas como actualizaciones optimistas y quieres manejar declarativamente los efectos secundarios de tus mutaciones. Y eso es algo donde ese concepto realmente no existe en SWR ahora mismo. Así que esa es una de las mayores razones por las que me gusta React Query. Bueno, diría que estás prejuiciado. Sí, estoy extremadamente sesgado. Muy bien Tanner, eso es todo el tiempo que tenemos para preguntas ahora mismo. Si tienes alguna pregunta más para Tanner, puedes ir a la sala de Zoom. Tanner, muchas gracias.
Comments