React Query: ¡Es hora de romper con tu "Estado Global"!

Rate this content
Bookmark

Una cantidad creciente de datos en nuestras aplicaciones React proviene de fuentes remotas y asíncronas y, aún peor, continúa disfrazándose como "estado global". En esta charla, obtendrás información sobre por qué la mayoría de tu "estado global" en realidad no es un estado en absoluto y cómo React Query puede ayudarte a buscar, almacenar en caché y gestionar tus datos asíncronos con una fracción del esfuerzo y el código al que estás acostumbrado.

Tanner Linsley
Tanner Linsley
30 min
02 Aug, 2021

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.

Available in English

1. Introducción a la Gestión del Estado Global

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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

Short description:

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.

QnA

React Query y Comunicación con el Servidor

Short description:

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

Short description:

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.

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

Everything Beyond State Management in Stores with Pinia
Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Using useEffect Effectively
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
Jotai Atoms Are Just Functions
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
A Practical Guide for Migrating to Server Components
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.
Announcing Starbeam: Universal Reactivity
JSNation 2022JSNation 2022
27 min
Announcing Starbeam: Universal Reactivity
Starbeam is a library for building reactive data systems that integrate natively with UI frameworks such as React, Vue, Svelte or Ember. In this talk, Yehuda will announce Starbeam. He will cover the motivation for the library, and then get into the details of how Starbeam reactivity works, and most importantly, how you can use it to build reactive libraries today that will work natively in any UI framework. If you're really adventurous, he will also talk about how you could use Starbeam in an existing app using your framework of choice and talk about the benefits of using Starbeam as the state management system in your application.
React Query and Auth: Who is Responsible for What?
React Advanced Conference 2021React Advanced Conference 2021
19 min
React Query and Auth: Who is Responsible for What?
Top Content
React Query manages server state on the client, and auth manages user sign in/sign up/sign out. Where do these two overlap, and how do you separate concerns? This talk proposes a data flow with custom hooks for both auth and React Query to manage authentication status and user profile updates.

Workshops on related topic

Rethinking Server State with React Query
React Summit 2020React Summit 2020
96 min
Rethinking Server State with React Query
Top Content
Featured Workshop
Tanner Linsley
Tanner Linsley
The distinction between server state and client state in our applications might be a new concept for some, but it is very important to understand when delivering a top-notch user experience. Server state comes with unique problems that often sneak into our applications surprise like:
- Sharing Data across apps- Caching & Persistence- Deduping Requests- Background Updates- Managing “Stale” Data- Pagination & Incremental fetching- Memory & Garbage Collection- Optimistic Updates
Traditional “Global State” managers pretend these challenges don’t exist and this ultimately results in developers building their own on-the-fly attempts to mitigate them.
In this workshop, we will build an application that exposes these issues, allows us to understand them better, and finally turn them from challenges into features using a library designed for managing server-state called React Query.
By the end of the workshop, you will have a better understanding of server state, client state, syncing asynchronous data (mouthful, I know), and React Query.
State Management in React with Context and Hooks
React Summit Remote Edition 2021React Summit Remote Edition 2021
71 min
State Management in React with Context and Hooks
WorkshopFree
Roy Derks
Roy Derks
A lot has changed in the world of state management in React the last few years. Where Redux used to be the main library for this, the introduction of the React Context and Hook APIs has shaken things up. No longer do you need external libraries to handle both component and global state in your applications. In this workshop you'll learn the different approaches to state management in the post-Redux era of React, all based on Hooks! And as a bonus, we'll explore two upcoming state management libraries in the React ecosystem.