Video Summary and Transcription
React Query es una popular biblioteca de sincronización de datos utilizada por desarrolladores independientes, startups y Fortune 500, con más de 1,200 commits y 250 contribuyentes. La charla cubre la creación de una versión simplificada de React Query llamada React Query Lite. Explora conceptos como el almacenamiento en caché, la búsqueda en segundo plano y la recolección de basura. El orador también discute el uso de observadores de consultas y la integración de React Query con React. La charla concluye con una discusión sobre las herramientas de React Native, las pruebas y la estabilidad de la API de React Query.
1. Introducción a React Query
Hola a todos. Soy Tannyor Lindsly, cofundador e ingeniero de UI UX en Nozzle. Creé la pila TAN, un software de código abierto para React y JavaScript. React Query, la biblioteca que construí, ha ganado una popularidad significativa y es ampliamente adoptada. Ha recibido más de 1,200 commits de 250 contribuyentes y es utilizada por desarrolladores independientes, startups y Fortune 500s. React Query Essentials, mi curso oficial, proporciona material de aprendizaje completo. React Query también aparece en artículos externos, tutoriales y frameworks como Blitz.js.
Hola a todos. Mi nombre es Tannyor Lindsly, y soy cofundador e ingeniero de UI UX en Nozzle, y soy el creador de la pila TAN, donde estamos haciendo todo lo posible para construir software de código abierto para React y JavaScript.
Hace casi exactamente un año, di una charla aquí en la Cumbre de React, donde desglosé las diferencias entre el estado del servidor y el estado del cliente y los desafíos que surgen al intentar gestionar el estado del servidor por tu cuenta. En esa misma charla, presenté una herramienta llamada React Query. Es una biblioteca que construí con la esperanza de aliviar la mayoría de los desafíos de la obtención de data que experimentamos en nuestras aplicaciones de React.
Y desde aquel día hace un año, React Query ha recibido más de 1,200 commits de más de 250 contribuyentes. Y ha sido adoptada por desarrolladores independientes, startups, Fortune 500s y un puñado de equipos de empresas que probablemente no estoy legalmente autorizado a mencionar. También lancé React Query Essentials que es mi curso oficial para aprender la biblioteca de arriba a abajo. Y React Query ha recibido una tonelada de cobertura de artículos externos y tutoriales y material de formación de primera clase como Epic React. Incluso se está utilizando como una característica central para los frameworks emergentes como Blitz.js. Todo este increíble crecimiento y atención ha ayudado a React Query a convertirse en una de las mejores bibliotecas de obtención de data para React y estoy muy agradecido por todo su uso y apoyo que ha recibido hasta ahora. Así que muchas gracias.
2. Construyendo una versión mini de React Query
React Query es una biblioteca de sincronización de datos que coordina la obtención, almacenamiento en caché y actualización de datos en su aplicación. Proporciona datos almacenados en caché mientras los actualiza en segundo plano con la frecuencia que tenga sentido. Puede configurar React Query para hacer otras cosas interesantes como sondeo de intervalos, precarga, SSR, paginación, y tiene DevTools dedicados. Hoy, construiremos nuestra propia versión de React Query llamada React Query Lite, que tendrá autofetching, autocaching y recolección de basura. El objetivo es hacerlo en menos de 150 líneas de código.
Hasta ahora, algunos de ustedes probablemente se están preguntando, ¿qué es React Query? Así que para aquellos de ustedes que no están familiarizados con los conceptos generales de la biblioteca, van a querer volver y escuchar algunas de mis charlas anteriores y leer la documentación para familiarizarse. Pero sólo para que todos estemos en la misma página hoy, les daré un rápido resumen de dos minutos de qué es React Query y qué puede hacer.
En pocas palabras, React Query es una biblioteca de sincronización de datos. Coordina la obtención, almacenamiento en caché y actualización de datos en su aplicación. Los datos que maneja pueden provenir de casi cualquier lugar siempre y cuando devuelva una promesa. Se basa en el concepto de obsoleto mientras se revalida, lo que significa que proporciona datos almacenados en caché tan a menudo como sea posible mientras actualiza esos datos en segundo plano tan a menudo como tenga sentido para los componentes que lo consumen. Así que usted proporciona la lógica de obtención y se encarga de todo lo demás automáticamente. Puede colocar las consultas de React Query en cualquier lugar de su aplicación de React a cualquier profundidad, y nunca tiene que preocuparse por hacer solicitudes de red duplicadas o gestionar el estado global o usar el contexto.
Puede configurar React Query para hacer otras cosas interesantes como sondeo de intervalos, precarga, SSR, paginación, hay muchas cosas interesantes que React Query puede hacer. Una de mis favoritas es que tiene DevTools dedicados. Hay mucho que podría decir sobre React Query ahora mismo. Podríamos pasar horas hablando de las cosas interesantes que puede hacer y eso es realmente lo que hago en mi curso de Essentials de React Query. Así que en lugar de hacer eso de nuevo y dar otra charla sobre cómo usar React Query, pensé que sería divertido hoy hacer algo diferente y mostrarles cómo podríamos construir nuestra propia versión de React Query, o al menos una versión miniatura. La llamaremos React Query Lite. Y al hacerlo, esperamos poder obtener una mejor comprensión de cómo funciona conceptualmente bajo el capó.
Para hacer esto, vamos a construir un Cliente de Consulta, un Proveedor de Cliente de Consulta, y un hook Use Query. Y ese hook Use Query va a tener autofetching, autocaching, recolección de basura, y también podremos configurar el tiempo obsoleto y el tiempo de caché. Y la gran esperanza aquí... Estoy esperando... que podamos hacerlo en menos de 150 líneas de código. Así que haremos nuestro mejor esfuerzo. Veremos qué pasa. Hay una advertencia aquí. Quiero decirles que el código que estamos a punto de escribir está muy poco probado. No es seguro en cuanto a tipos. Definitivamente es ingenuo y está lleno de casos límite. No deberías usar esto en producción. Ni en desarrollo, para el caso. Así que, sólo para fines de aprendizaje. Va a ser muy divertido.
3. Resumen de la Aplicación
Vamos a sumergirnos en la aplicación que he construido. Obtiene una lista de publicaciones y las muestra individualmente. React Query se encarga de la caché y la obtención en segundo plano. Ahora, vamos a explorar la aplicación.
Así que vamos a ello. a una aplicación que he construido. Y si has utilizado alguno de los ejemplos de React Query, esto debería parecerte bastante familiar. Es una aplicación que obtiene una lista de publicaciones. En este caso, cinco. Podemos hacer clic en ellas y cargará una publicación individual con un título y el cuerpo de la publicación. Podemos pulsar el botón de retroceso. Y puedes ver que React Query ya está haciendo su trabajo aquí. Estamos utilizando el React Query normal, donde si hemos cargado una publicación o una lista de publicaciones, entonces simplemente carga automáticamente la versión en caché. Y luego obtiene en segundo plano, si lo pulsas de nuevo, puedes ver ese pequeño fondo verde obteniendo. Así que esto es genial. Y React Query está haciendo su trabajo. Vamos a repasar la aplicación realmente rápido y te mostraré lo que está sucediendo.
4. Componentes de la Aplicación y Hooks Personalizados
Tenemos un cliente de consulta, componente de aplicación, y hooks personalizados utilizando UseQuery. El hook UsePosts obtiene publicaciones, y el componente Posts las muestra. La vista de Post individual muestra publicaciones individuales. También tenemos una función de sleep para simular retrasos de la API.
Aquí tenemos un cliente de consulta que estamos creando. Tenemos el componente de aplicación aquí que es básicamente solo un router donde podemos establecer un ID de post y ver ya sea la lista de publicaciones o una vista detallada de una publicación. Tenemos nuestras React Query DevTools aquí y todo está envuelto en nuestro proveedor de cliente.
Ahora tenemos nuestros hooks personalizados que están utilizando UseQuery. Así que aquí está nuestro hook UsePosts que está llamando a UseQuery con la postKey y la función de consulta para obtener algunas publicaciones. También tenemos StaleTime y CacheTime que usaremos más tarde.
Aquí está el post individual, el hook UsePosts, que toma un ID de post, configura la clave de consulta y la función de consulta para obtener el post individual. Y aquí están nuestros componentes de visualización, el componente Posts donde estamos cargando todas las publicaciones, pasando por nuestros estados de carga y error, y finalmente mostrando nuestra lista de publicaciones. Y también tenemos nuestro indicador de búsqueda en segundo plano justo aquí. Hasta nuestra vista de Post individual, tenemos el ID del post que estamos pasando al hook UsePosts , nuestra consulta de post individual, y estamos haciendo exactamente lo mismo, solo un estado de carga y error aquí, y finalmente mostrando el post individual junto con otro indicador de actualización en segundo plano. Y aquí hay una pequeña función de sleep para que podamos hacer que la API que es realmente rápida parezca un poco lenta, para que podamos ver esos indicadores de carga.
5. Reemplazando React Query con ReactQueryLite
Nuestro primer paso es reemplazar la actual React Query con un nuevo archivo llamado ReactQueryLite. Necesitamos satisfacer al proveedor del cliente de consulta que nos está dando un error creando un contexto. Para manejar el error en el hook de uso de consulta, podemos crear una respuesta ficticia que indica que todo está cargando. Esto nos lleva a un estado de funcionamiento donde estamos renderizando algo.
Entonces, nuestro primer paso será eliminar la actual consulta de React y reemplazarla con un nuevo archivo, un archivo en blanco llamado ReactQueryLite. Y obviamente, todo se va a romper, así que vamos a entrar en nuestro archivo ReactQueryLite y ver qué está pasando.
Tenemos un proveedor de cliente de consulta, el cliente de consulta, use query, y las DevTools. Justo de entrada, probablemente no llegaremos a DevTools, así que simplemente devolvamos null en eso y satisfacemos ese requisito.
Lo siguiente que vamos a hacer es que vamos a necesitar satisfacer a este proveedor de cliente de consulta que nos está dando un error. Así que voy a tomar nuestro pequeño proveedor de cliente de consulta code y lo pegaré aquí, y lo que está pasando aquí es que tenemos los hijos que estamos pasando. Toma al cliente, y luego está pasando ese cliente a todos los hijos. Vamos a necesitar un contexto para hacer esto funcionar, así que vamos a crear un contexto muy rápido. Tenemos que crear un contexto, y ahora estamos obteniendo un error porque estamos tratando de leer la propiedad status de indefinido en el hook de uso de consulta. Así que simplemente vamos a juntar una especie de respuesta ficticia de este hook de uso de consulta que dice que todo está cargando todo el tiempo. No data, error indefinido, is fetching true. Así que eso nos lleva al menos a un estado de funcionamiento donde estamos renderizando algo.
6. Creando el Objeto de Consulta
Una consulta es un objeto con estado y una función de búsqueda. Crearemos una función llamada createQuery que toma la clave de consulta y la función de consulta como parámetros. Configura el objeto de consulta con el estado inicial, proporciona una función setState para actualizar el estado, y una función de búsqueda para iniciar la búsqueda. Esto es todo JavaScript puro por ahora, pero lo integraremos con React pronto.
La siguiente pregunta que debemos hacernos es ¿qué es exactamente una consulta? Bueno, una consulta al final del día probablemente solo va a ser un objeto, como un objeto de consulta que tiene algún estado en él con una función de búsqueda. Entonces, ¿por qué no hacemos una nueva función aquí abajo llamada createQuery. Va a compartir parte de la firma de nuestro hook useQuery, por lo que la clave de consulta y la función de consulta se van a pasar aquí. Crearemos el nuevo objeto de consulta y lo configuraremos con un estado inicial. Es ese mismo estado que estamos usando aquí. Y vamos a tener una función setState que nos permite actualizar nuestro estado de consulta y una función de búsqueda que nos permite iniciar la búsqueda de eso. Esto es todo solo JavaScript por ahora. Llegaremos a conectarlo con React aquí en un minuto.
7. Actualizador de Estado y Función de Búsqueda
Después de configurar el actualizador de estado, creamos una función de búsqueda asíncrona. Establece el estado isFetching en verdadero y borra cualquier error. En un bloque try-catch, llamamos a la función de consulta y manejamos los casos de éxito y error. Finalmente, establecemos queryPromise en nulo y isFetching en falso. Para evitar solicitudes duplicadas, utilizamos la propiedad query.promise y envolvemos la función de búsqueda en lógica que verifica la existencia de una promesa. Creamos un método de suscripción para soportar múltiples instancias de useQuery y notificar a los suscriptores cuando el estado cambia.
Entonces, después de haber hecho eso, necesitamos trabajar un poco con nuestro actualizador de estado. Así que setState va a tomar una función de actualización y básicamente solo ejecutará esa función de actualización con el estado existente y devolverá el nuevo estado, algo así como un reductor. O si has usado setState antes con React, es muy parecido a eso.
A continuación, tenemos nuestra función de búsqueda, y nuestra función de búsqueda va a ser asíncrona por ahora. Lo que hace esta función de búsqueda es, lo primero que queremos hacer es usar nuestra nueva función setState en la consulta para establecer setIsFetching en verdadero y borrar el error. Luego, en un bloque try-catch, intentaremos llamar a nuestra función de consulta, así que usaremos await aquí, obtendremos los data de la función de consulta, y luego si todo tiene éxito vamos a poner el estado de éxito y agregar nuestros data. Y luego en nuestro catch, si tenemos un error, vamos a hacer lo mismo, solo el estado de error con el error. Y finalmente, literalmente, finalmente, vamos a establecer queryPromise en nulo y query.setState vamos a establecer setIsFetching en falso.
Así que este quirky.promise aún no existe, pero lo vamos a necesitar. Así que vamos a establecer la promesa en nulo aquí arriba, desde el principio. Y lo que esto va a hacer es permitirnos comenzar a configurar algo de desduplicación. Así que si la función de consulta ya se está ejecutando o está en progreso, no queremos dispararla de nuevo. Así que vamos a usar esa propiedad query.promise para hacer algo de magia con las promesas. En lugar de hacer esta función Fetch async aquí, la vamos a envolver en otra lógica. La vamos a envolver en este bloque justo aquí. Así que si aún no hay una promesa, vamos a asignar esa promesa a una nueva promesa que viene de esta función asíncrona. Y podemos simplemente volcar toda nuestra lógica existente en esa función justo allí. Así que dice que si no hay una promesa, entonces inicia una nueva función Fetch y asígnala a la promesa. Y así que cualquier otra vez que llamemos a Fetch si ya hay una promesa, simplemente la vamos a devolver aquí mismo. Así que si no hay promesa, entonces diremos return query.promise. Y eso se encarga de nuestro problema de desduplicación, que es una forma bastante elegante y fácil de hacer eso. Queremos asegurarnos de que en el finally, cuando termine, establecemos esa promesa de consulta en nulo para que podamos dispararla de nuevo. Así que no podemos conectar esta función de creación de consultas directamente a nuestro hook useQuery. Tenemos que permitir que las consultas sean compartidas por múltiples instancias de useQuery, así que vamos a tener que crear algún soporte de suscripción para todo esto, y vamos a empezar a hacer eso en nuestra consulta, en nuestra función createQuery aquí. Voy a crear un nuevo método aquí llamado subscribe. Va a tomar un suscriptor, que por ahora es solo un objeto, y vamos a empujar eso en query.subscribers, así que voy a necesitar suscriptores aquí arriba que van a ser un array. Y luego va a devolver una función de cancelación de suscripción, que simplemente eliminará eso de la lista de suscriptores cuando lo llamemos. Y también necesitamos actualizar nuestra función setState aquí arriba para que cada vez que llamemos a setState notifiquemos a todos los suscriptores. Pasamos por ellos y llamamos a subscriber.notify. Y solo voy a mover esto aquí abajo, para mantener las cosas organizadas.
8. Almacenando y Recuperando Consultas con Query Client
Necesitamos tener un lugar para almacenar estas consultas una vez que las creamos. Ahí es donde entra en juego el cliente de consulta. Configuramos un constructor para que cuando llamamos a newQueryClient establecemos this.queries a un array vacío. Configuraremos un nuevo método de clase llamado getQuery. Y getQuery va a obtener una consulta existente en esa lista o simplemente crear una y añadirla a ella y luego devolverla. Para hacer eso vamos a hacer un hash de la clave de consulta que estamos obteniendo de las opciones de aquí arriba y simplemente vamos a usar json.stringify para hacer eso, para obtener un hash de consulta.
Y ahora nuestra función createQuery se ve bastante bien, pero nos falta otra pieza vital. Necesitamos tener un lugar para almacenar estas consultas una vez que las creamos. Y ahí es donde entra en juego el cliente de consulta. Así que si subimos aquí al cliente de consulta, esto es solo una clase y podemos hacer esto realmente básico. Podemos simplemente configurar un constructor para que cuando llamamos a newQueryClient establecemos this.queries a un array vacío. Esto va a ser solo un array para todas nuestras consultas. Y vamos a configurar un nuevo método de clase aquí llamado getQuery. Y getQuery va a obtener una consulta existente en esa lista o simplemente crear una y añadirla a ella y luego devolverla. Así que está creando o obteniendo lo que le pedimos que construya para nosotros. Para hacer eso vamos a hacer un hash de la clave de consulta que estamos obteniendo de las opciones de aquí arriba y simplemente vamos a usar json.stringify para hacer eso, para obtener un hash de consulta. Una vez que tenemos ese hash, podemos intentar encontrar una consulta existente simplemente recorriéndolas y comparando los hashes. Si no tenemos una consulta ya aquí vamos a ejecutar nuestra función createQuery con las opciones que son solo la clave de consulta, la función de consulta, todas esas cosas. Pero tenemos que pasarle el cliente de consulta, también, con el que lo estamos creando. Así que vamos a bajar a createQuery y vamos a añadir aquí el cliente muy rápido para que esa firma coincida. Y luego empujamos esa consulta en this.queries para el cliente de consulta y luego la devolvemos. Así que, de todos modos, siempre estamos devolviendo una consulta aquí. Así que estamos creándola o agarrando una existente.
9. Conectando Consultas y Creando Observadores
Necesitamos asegurarnos de que nuestra función createQuery soporte la clave de consulta y el hash de consulta. Necesitamos un observador de consulta para coordinar todas las suscripciones y usar consultas varias veces. El observador de consulta crea un objeto observador con los métodos notify, getResult y subscribe. El método subscribe toma un callback para volver a renderizar el componente y lo asigna a la propiedad observer.notify. Nos suscribimos a la consulta con el observador, obtenemos la función de cancelar suscripción y llamamos a query.fetch para habilitar la recuperación automática. En la función useQuery, obtenemos el cliente del contexto y trabajamos con el observador para manejar los datos.
Entonces, lo siguiente que necesitamos hacer es asegurarnos de que nuestra función createQuery soporte nuestra clave de consulta y el hash de consulta. Así que vamos a hacer que la clave de consulta se almacene allí y que el hash de consulta siempre esté dentro de allí para que podamos identificar la consulta.
Entonces, desde este punto, todavía estamos a un paso de conectar nuestras consultas a nuestro hook useQuery. Todavía necesitamos una cosa más en el medio para coordinar todas las suscripciones y asegurarnos de que podemos usar nuestras consultas varias veces en la aplicación y realmente solo crear una consulta. Así que vamos a hacer eso con algo llamado observador de consulta. Tengo una nueva función aquí llamada createQuery observer que es muy similar a la de arriba. Toma un cliente y alguna información de la consulta y va a crear un observador para nosotros. También va a crear una consulta aquí si es necesario.
Entonces vamos a llamar a createQuery observer. Va a obtener o crear la consulta y luego va a crear un nuevo objeto observador. Y este objeto observador tiene un par de métodos que vamos a revisar. El primero es notify que por ahora está vacío pero vamos a asignarlo a algo aquí en un segundo. El siguiente es getResult que simplemente nos va a dar el estado de las consultas que este observador está observando cuando lo llamamos. Y el tercero es subscribe. Este es el que vamos a llamar desde nuestro hook usedQuery. Así que vamos a pasarle un callback que probablemente será una función de renderizado para volver a renderizar nuestro componente cuando algo cambie. Simplemente vamos a tomar ese callback y asignarlo a nuestra propiedad observer.notify. Y luego vamos a suscribirnos a la consulta misma con este observador que estamos creando aquí. Y luego vamos a obtener la función de cancelar suscripción y devolverla. Y luego la parte más importante para habilitar nuestra recuperación automática es este query.fetch aquí. Cada vez que nos suscribimos a un nuevo observador queremos asegurarnos de que está iniciando una recuperación. Así que simplemente vamos a llamar a query.fetch aquí mismo. Y eso también se deduplicará bajo el capó. Así que finalmente con toda esta lógica podemos empezar a conectar nuestra función useQuery. Así que volvamos a useQuery y veamos cómo todo esto se junta. Claramente no vamos a devolver datos ficticios sino que vamos a hacer un montón de cosas con el observador que podemos crear dentro de aquí. La primera sección de esto aquí es que necesitamos saber con qué cliente estamos tratando. Y obtenemos eso del contexto que estamos usando aquí pasando a través de nuestro proveedor de contexto. Y lo vamos a recoger aquí mismo con react.useContext. Así que ahí está el cliente.
10. Lógica del Observador y Creación del Observador de Consulta
Esta sección introduce la lógica del observador y la creación de un observador de consulta por instancia de useQuery. El observador se almacena en una ref y se inicializa con el cliente, la clave de consulta y la función de consulta obtenida de las opciones de useQuery.
Este próximo bloque aquí es solo una forma muy simple de volver a renderizar un componente en el que se está utilizando un hook. Así que solo una pequeña función de re-renderizado que podemos forzar al componente a volver a renderizar. La siguiente parte es la lógica del observador. Así que queremos almacenar este observador en esta ref y solo queremos crear un observador por instancia de useQuery. Así que si no existe, vamos a crear un observador de consulta. Le pasaremos el cliente que obtuvimos del contexto. Pasaremos la clave de consulta y la función de consulta que estamos obteniendo de nuestras opciones de useQuery. Y luego vamos a almacenar eso en la ref del observador.
11. Finalizando la Lógica del Observador
Devolvemos la función getResult de nuestro observador, que devuelve el estado de la consulta. Nos suscribimos al observador y volvemos a renderizar nuestro componente cuando ocurren cambios. Funciona bien, con estados de carga y refetching en segundo plano. Pero todavía hay algunas cosas más que hacer.
A partir de ahí, vamos a devolver la función getResult de nuestro observador. Si recuerdas, devuelve el estado de la consulta. Así que va a devolver el estado de la consulta para lo que sea que el observador esté conectado. Y luego establecemos un efecto aquí, siempre que esto se monte, para que podamos suscribirnos a ese observador. Y cada vez que algo cambia en el observador, vamos a volver a renderizar nuestro componente que useQuery se está utilizando. Así que, técnicamente, esto debería funcionar justo ahora. Vamos a revisar nuestras líneas de code. Estamos en 130, y eso es genial. Si venimos aquí, las cosas deberían estar cargando, y puedes ver que está funcionando muy bien. Si recargamos la página, obtenemos ese estado de carga duro, pero solo para las primeras veces que estamos golpeando cosas. Y puedes ver que tenemos ese refetching en segundo plano que está sucediendo muy bien. Así que esto funciona muy bien ya, pero todavía tenemos algunas cosas más que necesitamos hacer.
12. Añadiendo Tiempo Estancado
Necesitamos agregar tiempo estancado a nuestra función use query y crear un observador de consultas. Comprobaremos la última marca de tiempo actualizada y la compararemos con el valor del tiempo estancado. Si es mayor, iniciaremos una consulta de búsqueda. Después de habilitar el tiempo estancado en nuestra aplicación, podemos ver que la actualización en segundo plano solo ocurre después de que ha pasado el tiempo especificado.
Lo siguiente que necesitamos hacer es agregar tiempo estancado. Necesitamos ir a nuestra función use query aquí mismo, y simplemente vamos a agregar tiempo estancado. Y el tiempo estancado realmente necesita ser pasado hacia abajo, a través de nuestro create query observer aquí mismo. Así que iremos a nuestro create query observer, y lo recogeremos aquí mismo. Y el tiempo estancado simplemente se va a predeterminar a cero, así que vamos a predeterminarlo a cero aquí mismo. Luego lo que necesitamos hacer es reorganizar un poco esta lógica. Cuando nos suscribimos a un observador, en lugar de llamar a query.fetch, queremos hacer algunas comprobaciones primero. En lugar de hacer query.fetch, voy a llamar a algo llamado observer.fetch, y simplemente crearemos una nueva función aquí mismo en nuestro observador. Y este fetch va a tener alguna lógica condicional dentro de aquí, donde vamos a estar comprobando la última marca de tiempo actualizada de la consulta. Y vamos a tomar la fecha de ahora, o el tiempo ahora, menos nuestra última marca de tiempo actualizada, y si eso es mayor que nuestro tiempo estancado que hemos definido, vamos a iniciar el query.fetch. Y para que todo eso funcione, necesitamos ir a donde estamos estableciendo el éxito para nuestra consulta y asegurarnos de que añadimos esa marca de tiempo, última actualización. Dicho esto, deberíamos volver a nuestra aplicación, y vamos a activar el tiempo estancado para ambos y ver qué pasa. Si navegamos por ahí, no deberíamos estar obteniendo una actualización en segundo plano hasta que hayan pasado tres segundos. Y puedes ver que si vuelvo atrás, no lo vemos allí, pero lo veremos después de que hayan transcurrido los tres segundos. Así que el tiempo estancado está funcionando, y eso es genial.
13. Añadiendo Tiempo de Caché y Recolección de Basura
Vamos a añadir tiempo de caché a nuestra función use query y crear un observador de consultas. Programaremos la recolección de basura para las consultas cuando se elimine el último suscriptor. El tiempo de caché se establecerá por defecto en cinco minutos. Estableceremos un tiempo de espera para el tiempo de caché y eliminaremos la consulta del cliente cuando expire. También añadiremos una forma de deshacer la recolección de basura y prevenirla cuando una consulta esté suscrita. Al añadir esta lógica, tendremos la recarga cuando volvamos a enfocar la ventana.
Lo siguiente que vamos a hacer es, veamos, nuestras líneas de code están en 142, así que estamos, oh, eso es React Querylight, 140. Así que estamos bastante cerca, pero aún podemos añadir algunas cosas más.
Lo último que vamos a hacer es el tiempo de caché. Así que el tiempo de caché también va a ser dirigido a través de use query. Vamos a hacer el tiempo de caché justo aquí. Y lo mismo, vamos a pasar eso a través de nuestra creación de observador, y vamos a recogerlo justo aquí, pero el tiempo de caché necesita ser dirigido un poco más allá. Así que vamos a pasar el tiempo de caché a través de la función get query aquí. Get query se pasa hasta aquí, las opciones se lanzan en la función create query, y aquí es donde lo recogemos. Y vamos a establecer eso por defecto en cinco minutos simplemente porque eso es lo que es en React Query. Así que eso es bastante divertido. Y este tiempo de caché es un poco más complicado, pero es bastante divertido.
Lo que necesitamos hacer es asegurarnos de que cuando se elimine el último suscriptor de una consulta que lo comprobamos y decimos que si no hay más suscriptores, vamos a programar una recolección de basura en esta consulta. Así que vamos a añadir esa función schedule GC. Simplemente la añadiremos aquí. Vamos a establecer un tiempo de espera que dure el tiempo de caché. Así que cuando el tiempo de caché se agote, vamos a eliminar esta consulta de nuestro cliente de consultas y a recogerla como basura. Vamos a necesitar esa variable de tiempo de espera de recolección de basura también. Así que vamos a añadirla aquí arriba y simplemente la estableceremos en null. Y también necesitamos una forma de deshacer esto también. Así que vamos a hacer un unschedule GC recolección de basura y eso simplemente va a borrar ese tiempo de espera si se llama, y queremos borrar eso si, en cualquier momento la consulta se suscribe. Así que simplemente lo haremos aquí. Cada vez que abrimos una nueva suscripción a una consulta queremos asegurarnos de que no va a ser recogida como basura más. Y eso honestamente debería ser todo lo que necesitamos. Así que si volvemos aquí y añadimos nuestro tiempo de caché de cinco segundos, lo que va a suceder es que si esperamos cinco segundos antes de cargar este post, esa lista principal de posts de nuevo, vas a ver un estado de carga duro aquí. Y eso es porque la consulta ya había sido recogida como basura de la lista después de cinco segundos.
Esas son todas las características base que hemos hablado. Y creo que tenemos tiempo para dos más que no explicaré demasiado, pero simplemente las meteremos ahí. Vamos a subir aquí al proveedor de cliente de consulta y simplemente meteremos esta lógica aquí. Y ahora, de repente, tenemos recarga cuando volvemos a enfocar la ventana. Así que no tenemos que estar navegando por ahí.
14. Herramientas de Desarrollo y Conclusión
Podemos volver y quitar nuestro tiempo obsoleto y tiempo de caché, lo que hará esto un poco más evidente. Y cada vez que enfocamos la ventana, se va a actualizar en segundo plano. Tenemos un impresionante componente de herramientas de desarrollo aquí también. Las herramientas de desarrollo necesitan una forma de suscribirse al cliente de consulta en sí. Así que subiremos al cliente de consulta, añadiremos this.subscribers. Añadiremos un método de suscripción a esta clase que es muy similar a lo que hicimos con la consulta. Y luego también añadiremos un método de notificación aquí también, para que podamos llamar a notificar y notificar a cada suscriptor que necesita volver a ejecutarse. Puedes ver que nuestro post dice éxito, pasamos al siguiente, obtenemos una pequeña indicación de nuestra clave de consulta y éxito y este está inactivo pero si volvemos vuelve a entrar en juego. Si vamos por aquí y cargamos uno nuevo. Así que hay algunas herramientas de desarrollo. Realmente aprecio que hayan escuchado lo que tenía que decir hoy. Creo que React Query es una gran herramienta y estoy súper emocionado por lo que el futuro tiene reservado para React Query. En el corazón de React Query, realmente hay una impresionante comunidad de patrocinadores y contribuyentes y usuarios y personas que realmente han ayudado a hacer lo que es hoy y me gustaría decir gracias a todas esas personas.
Podemos volver y quitar nuestro tiempo obsoleto y tiempo de caché, lo que hará esto un poco más evidente. Y cada vez que enfocamos la ventana, se va a actualizar en segundo plano. Y luego también, tenemos un impresionante componente de herramientas de desarrollo aquí también. Simplemente voy a pegar todo el componente de herramientas de desarrollo. Y sé que estamos quedándonos cortos de tiempo, pero esto va a ser divertido. Así que busquemos las herramientas de desarrollo. Simplemente lo pondremos en la parte inferior. Herramientas de desarrollo realmente simples, pero sí depende de algunas cosas. Y solo necesitamos añadir esas cosas muy rápido.
Las herramientas de desarrollo necesitan una forma de suscribirse al cliente de consulta en sí. Así que subiremos al cliente de consulta, añadiremos this.subscribers. Añadiremos un método de suscripción a esta clase que es muy similar a lo que hicimos con la consulta. Y luego también añadiremos un método de notificación aquí también, para que podamos llamar a notificar y notificar a cada suscriptor que necesita volver a ejecutarse. Dicho esto, creo que solo necesitamos exportar nuestras herramientas de desarrollo de React Query. Y sabes qué, simplemente voy a subir la parte inferior de la ventana. Para que podamos verlo mejor. Y ahí están nuestras herramientas de desarrollo. Así que también necesitamos asegurarnos de que está notificando, veamos que tenemos set state aquí. Necesitamos asegurarnos de que también estamos notificando al cliente cuando establecemos el estado o si no las herramientas de desarrollo no se van a actualizar. Y probablemente deberíamos notificar al cliente en la recolección de basura también. Así que hagámoslo ahí. Ahí vamos. Puedes ver que nuestro post dice éxito, pasamos al siguiente, obtenemos una pequeña indicación de nuestra clave de consulta y éxito y este está inactivo pero si volvemos vuelve a entrar en juego. Si vamos por aquí y cargamos uno nuevo. Así que hay algunas herramientas de desarrollo.
Sé que se nos acabó el tiempo así que volvamos y terminemos las cosas aquí. Realmente aprecio que hayan escuchado lo que tenía que decir hoy. Creo que React Query es una gran herramienta y estoy súper emocionado por lo que el futuro tiene reservado para React Query. En el corazón de React Query, realmente hay una impresionante comunidad de patrocinadores y contribuyentes y usuarios y personas que realmente han ayudado a hacer lo que es hoy y me gustaría decir gracias a todas esas personas. Asegúrate de venir a hablar conmigo un poco más en el chat.
Discusión y Preguntas y Respuestas
Siempre estoy abierto a una buena charla. Discutamos algunos de los resultados de la encuesta. Tenemos algunas preguntas increíbles de la gente en el Discord. Por cierto, fue una charla muy divertida. Repasemos estas preguntas de la audiencia. Aprilian pregunta, ¿la API V3 va a permanecer estable al menos unos meses más o debería esperar a la V4 antes de migrar proyectos existentes entre versiones mayores? Definitivamente es estable. Deberías actualizar ahora. Pero si lanzamos una V4, no va a haber grandes cambios disruptivos como lo fue con la V3. Serán pequeños. Vamos a tomarlo con calma de aquí en adelante. Así que no te preocupes.
Siempre estoy abierto a una buena charla. Puedes encontrarme en tanstack.com, nozel.io, y mi nombre de usuario es tannerlindsley en casi todos los demás lugares. Así que, gracias. Genial, esa fue una charla muy interesante. Muchas gracias, Tanner.
Discutamos algunos de los resultados de la encuesta. Entonces, Tanner quería saber si has usado React Query antes y el 68% dijo que aún no lo han probado, pero el 25% lo está usando ahora y el 7% lo usó antes. Tenemos algunas personas experimentadas con React Query en la audiencia. Recibimos algunas preguntas increíbles de la gente en el Discord. Por cierto, fue una charla muy divertida. Estoy muy impresionado por tus habilidades de codificación en vivo. Los gremlins siempre aparecen cuando hago demostraciones en vivo, así que siempre es impresionante ver a la gente escribiendo code en vivo y que realmente funcione. Es mucho más fácil cuando solo estás pegando cosas. Ese es el truco. El desarrollo impulsado por copiar y pegar es real. Si hubiera ido letra por letra, no habríamos terminado a tiempo. Genial.
Vale. Así que repasemos estas preguntas de la audiencia. Entonces Aprilian pregunta, ¿la API V3 va a permanecer estable al menos unos meses más o debería esperar a la V4 antes de migrar proyectos existentes entre versiones mayores? Definitivamente es estable. Va a permanecer así por un tiempo. Deberías actualizar ahora. Pero si lanzamos una V4, no va a haber grandes cambios disruptivos como lo fue con la V3. Serán pequeños. Vamos a tomarlo con calma de aquí en adelante. Así que no te preocupes. Genial. Entonces, esa es una respuesta bastante definitiva. Usa la V3. Este nombre de usuario es complicado.
Herramientas de React Native y Pruebas
ALBSKJORR pregunta sobre las herramientas de desarrollo de React Native para ReactQuery. No conozco la fecha de lanzamiento. Jordie VD pregunta sobre los beneficios de ReactQuery sobre Apollo para GraphQL. ReactQuery es más fácil de entender, pero carece de la experiencia de primera clase de GraphQL. La forma sugerida de probar componentes usando UseQuery es con la Biblioteca de Pruebas de React. Publicaré el código en mi GitHub, pero no está listo para producción.
ALBSKJORR pregunta, ¿cuándo se lanzarán las herramientas de desarrollo de React Native para ReactQuery? No lo sé. No estoy trabajando en ellas. No puedo usar React Native ahora mismo. Así que espero que eso responda a tu pregunta. Yo tampoco. Deberías construirlas. Quien haya hecho esa pregunta, debería intentar construirlas. Eso sería genial. Eso sería realmente genial. Sí, nunca he hecho nada de desarrollo móvil, lo cual probablemente debería hacer en algún momento. Ni siquiera he probado React Native y Flutter.
Jordie VD pregunta, ¿tendría ReactQuery beneficios sobre algo como Apollo cuando se usa GraphQL? He oído a la gente decir que ReactQuery es más fácil de entender y manipular. Su API es un poco más simple, pero no tiene la experiencia de primera clase de GraphQL como la que obtendrías con Apollo o ... Así que no obtendrías la experiencia de primera clase que tendrías con Apollo o Urql. Genial.
Tenemos tiempo para una pregunta más y luego cualquier persona que tenga una pregunta restante, Tara estará en el chat espacial para responder más. Así que si quieres unirte allí, puedes hacer tu pregunta, incluso si no llegamos a ella aquí. Y la última pregunta es, ¿cuál es la forma sugerida de probar componentes usando UseQuery por MHI? Biblioteca de Pruebas de React. Pruébalo como lo usarías en tu aplicación. Puedes mirar las pruebas de React Query en sí mismas. Usamos la Biblioteca de Pruebas de React y no probamos ningún detalle de implementación. Así que hazlo así. Ahí lo tienes, genial, genial. Otro que haré muy rápido porque es un sí o un no, ¿publicarías el código para esto? Sí. Haré lo posible por publicar el código en mi GitHub. Genial. Genial. Pero escuchaste en la presentación que no uses este código. No está listo para producción. Sí, no uses este código. Si lo publico, no lo uses y por favor no me preguntes si es seguro para el modo concurrente o suspense listo. Genial, genial. Genial. Así que de nuevo, únete a Tanner en la sala de conferencias en el chat espacial y el enlace para unirte a eso está en la línea de tiempo.
Comments