0% encontró este documento útil (0 votos)
1 vistas8 páginas

React Query

React Query es una biblioteca para gestionar el estado asincrónico en aplicaciones React, optimizando las peticiones HTTP y manejando automáticamente estados como carga, errores y caché. Se instala fácilmente y requiere envolver la aplicación en un provider, permitiendo realizar consultas y mutaciones de datos con facilidad. Además, ofrece herramientas como DevTools para depurar y gestionar el estado de las consultas, así como soporte para técnicas avanzadas como prefetching e infinite scroll.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
1 vistas8 páginas

React Query

React Query es una biblioteca para gestionar el estado asincrónico en aplicaciones React, optimizando las peticiones HTTP y manejando automáticamente estados como carga, errores y caché. Se instala fácilmente y requiere envolver la aplicación en un provider, permitiendo realizar consultas y mutaciones de datos con facilidad. Además, ofrece herramientas como DevTools para depurar y gestionar el estado de las consultas, así como soporte para técnicas avanzadas como prefetching e infinite scroll.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

QUE ES?

-Es un gestor de estado asincronico (normalmente estado del servidor)


-React Query es parte del proyecto Tanstack que esta creando bibliotecas
utiles
-No hace peticiones HTTP, lo que hace es optiminar las peticiones HTTP
gestionando de manera automatica: Estados de carga, cache, errores,
reintentos automaticos, invalidacion de datos

COMO INSTALAR
-npm i @tanstack/react-query

//Eslint
-Nos va a ayudar con buenas practicas
npm i -D @tanstack/eslint-plugin-query

//Devtool para debugger


npm i @tanstack/react-query-devtools

CONFIGURACION INICIAL
-Tenemos que envolver nuestra aplicacion con un provider

import {QueryClientProvider, QueryClient} from "@tanstack/react/query"


import {ReactQueryDevtools} from "@tanstack/react-query-devtools"

const queryClient = new QueryClient()

<QueryClientProvider client={queryClient}>
<App/>
<ReactQueryDevtools />
</QueryClientProvider>

-queryClient es donde se va a almacenar el cache y mucho mas, basicamente


es el corazon

//Algun archivo API

import axios from 'axios'

const sampleApi = [Link]({


baseURL: '[Link]
})

export const getSample = async() => {


const res = await [Link] ('/products')
return [Link]
}

-Todo es axios normal


-Ahora en el arhivo que haremos la peticion:

import {useQuery} from '@tanstack/react-query'


import {getSample} from '...'

const {isLoading, data:products , isError, error} = useQuery({


queryKey: ['products'],
queryFn: getSample,
select: products => [Link]((a , b) => [Link] - [Link])
})

-En el queryKey nombramos la consulta, tambien es util para que se guarde


en memoria cache
-En el queryFn usamos la funcion que hara la consulta
-En cuanto se cargue el componente se hara la consulta
-Select es la manera como vamos a traer o seleccionar esos datos

//EXTRA
-Una forma de obtener todos los datos de un formulario para procesarlo
es:

const handleSubmit = (e) => {


[Link]();
const formData = new FormData([Link]);
const product = [Link] (formData);
}

-Esto me devuelve un objeto con todos los valores de los inputs en donde
su key es su name

MUTATION
-Es para mutar datos en el backend y no solo una consulta

import {useMutation, useQueryClient} from '@tanstack/react-query'


import {createSample} from '...'

const queryClient = useQueryClient()

const addSampleMutation = useMutation({


mutationFn: createSample,
onSuccess: () => {
[Link]('products')
}
})

-[Link](data) //Ponemos como parametro, lo que necesita


la funcion fn
-[Link]('nombreDeLaConsulta') // Es como decir que
el cache ya no es valido pq se actualizaro datos y que compare los datos
actuales con los datos que se va a solicitar al backend y lo actualice

-[Link]({ queryKey: ['products'] }) //Si no


funciona asi nomas

-Para cada consulta debemos crear un useQuery o un useMutation


USE QUERY

1. REFETCH

const {data, error, isLoading, refetch} = useQuery({


queryKey: [],
queryFn: fetchUsers,
retry: 5,
retryDelay: 1000,
})

refetch() //Esta funcion volvera a ejecutar la peticion


-Por defecto hace un retry si falla la peticion

2. IS LOADING / IS FETCHING
-La diferencia entre estos 2 es que isLoading toma en cuenta el valor
antiguo hasta que llega el nuevo, por tanto solo carga la primera vez y
no las siguientes
-isFetching toma en cuenta las peticiones y no asi los valores o datos

DEVTOOLS
-En aca podemos gestionar de mejor manera react query, por ejemplo
podemos hacer refetch, simular errores, loadings, ver todos nuestras
keys, etc.

-En aca podemos ver estados de las querys, como fresh, fetching, paused,
stale e inactive
-fresh quiere decir que los datos estan frescos y que no es necesario
volverlo a pedir, mientras que stale(por defecto) quiero decir que son
antiguos

-Si creamos varias querys con las mismas keys, de alguna manera estaran
sincronizados, es decir tendran los mismo valores

CUSTOM HOOK
-Si tenemos varias peticiones relacionadas, podemos ponerla todos en un
custom hook

AXIOS
-Se usa porque se soluciona varias molestias de fetch:
1. Parseo automatico de JSON
2. Manejo de errores HTTP, fetch solo lanza errores si falla la red, un
404 o 500 no entra en el catch
3. Interceptores, agregar el token a todas la peticiones y manejar
errores globales
4. Configuracion global

STALETIME, PLACEHOLDERDATA
useQuery({
querykey:..
queryFn:...
staleTime: 1000*60*60,
placeholderData: ...
initialData: ...
})
-Quiero decir que esta query estara en estado fresh por una hora,
entonces cuando utilice esta query, dentro de esa una hora retornara el
valor en cache

-En placeholderData podemos poner informacion por defecto mientras se


hace la peticion
-Con initialData podemos poner datos por defecto y junto con staleTime
podemos decir que esos datos por defecto estan frescos por tanto se
mantienen ese tiempo

SECCION 4
-Podemos seguir la nomenclatura de los keys de las querys similar al de
la url de las peticiones
-Para renderizar contenido md, podemos instalar 'react-markdown' y
simplemente usarlo como un componente mas

ENABLE
-Esto nos ayude de que un query si depende de otro, unicamente se ejecute
cuando el otro query hizo lo que tenga que hacer
-el useQuery puede tener:
..
enable: [Link] != undefined

-[Link]!.number
-con "! (non null assertion operator)" le dice a ts "Confia en mi, aqui
data no es null ni undefined"

PREFETCHING
-Consiste en realizar un fetching anticipado al poner el mouse encima del
item
-const queryClient = useQueryClient();
//Esto nos va a permitir obtener el query cliente del context el cual
contiene todas las querys

const handleMouseEnter = () => {


[Link]({
queryKey:...//Debe ser el mismo que el que se realiza dentro
del item
queryFn:...,
staleTime: 1000*60,
})
}

-Lo podemos poner dentro de un custom hook

export const useProductPrefetch = () => {


const queryClient = useQueryClient();

const prefetch = (id: number) => {


[Link](
["product", id],
() => getProduct(id),
{
staleTime: 1000 * 60
}
)
}

return prefetch;
}

-Podriamos mandar los parametros del prefetch mediante parametro del


custom hook

SET QUERY DATA


-Si al obtener nuestra lista de elementos, cada uno de los elementos ya
posee la informacion que se requiere en los detalles de cada item,
entonces podemos omitir hacer una peticion dentro del item con los datos
que ya obtuvimos

const presetData = () => {


[Link]([key de los items], data, {updatedAt:
[Link]() + 1000 * 60})
}
-UpdatedAt es la fecha cuando dejara de estar fresh los datos
-Si no lo ponemos entonces se hara una peticion y se comparara si los
datos nuevos son iguales a los antiguos

-Si a un custom hook se quiere enviar mas de 3 argumentos, entonces es


recomendable enviar un objeto y no como posiciones

-Si el orden de las keys no importa podemos mandarlo como un objeto:

queryKey: ['issues', {state}]

INFINITE SCROLL
-Es una texnica donde se cargan mas datos automaticamente cuando el
usuario llega al final de una lista

USE INFINITE QUERY


-Con esto react query guarda cada pagina:
[Link] = [
{ data: [/* página 1 */] },
{ data: [/* página 2 */] },
{ data: [/* página 3 */] }
]
-Cuando el usuario llega al final de la lista obtiene la siguiente pagina
y la agrega a pages

-.flat() // aplana un arreglo de arreglos en simplemente en un arreglo


con todos los elementos

EJEMPLO:

const issuesQuery = useInfiniteQuery({


queryKey: ['issue', {state, date}],
queryFn: ({pageParam=1}) => getIssues(state, date, pageParam)
staleTime: 1000 * 60,
getNextPageParams: (lastPage, pages) =>
[Link] > 0? [Link]+1 : undefined
})

//Luego
[Link]();

//Los datos que se obtiene lo debemos aplanar


const issues = [Link]?.[Link]() ?? [];

//Podemos saber si la siguiente pagina se esta cargando


[Link]

-Podemos crear un servidor con JSON server y asi mismo podemos aplicar
filtros, paginacion, etc.

const {data: products = []} = useQuery({})

- +numberString -> Convirte el string en numero

MUTACIONES
-Actualizacion como post, put, patch y delete

USE HOOK FORM


-Si tenemos una libreria de interfaces que directamente me da los
componentes, entonces no puedo usar el register, sinos el Controller

const {handleSumit, control} = useForm({


defaultValues: {}
});

const onSumit: SubmitHandler<FormInputs> = () => {


[Link](data);
}

...
<Controller
control={control}
name="title"
rules={{required: true}}
render={({field}) => (
<Input value={[Link]} onChange={[Link]}/>
)}
/>

-Es recomendablee llevar el mutation a un custom hook

const useProductMutation = () => {


const productMutation = useMutation({
mutationFn: () => {},
onSuccess: (data) => {
[Link](['products', {'filterKey':
[Link]}])
},
onSettled: ()=> {}
})
return productMutation;
}

-OnSettled es cuando ya termino


-Cuando se invalida la query, no se hace inmediatamente una peticion,
sinos cuando se lo solicita. El problema de invalidar es que pedimos
todos los datos nuevamente

Evitar invalidar
onSucess: (product) => {
[Link]<Product[]>(
['products',{filterKey: [Link]}],
(old) => {
if(!old) return [product];
return [...old, product];
}
);
}

Actualizacion Optimistas
-Basicamente consiste en insertar inmediatamente a la cache de la
peticion la informacion que estamos insertando, esto es util si el
servidor tarda en insertar o responder

onMutation: (product) => {


const optimisticProduct = {id: [Link] (), ...product};

[Link]({
[key de la query...],
(old) => {
if(!old) return [optimisticProduct];
return [...old, optimisticProduct];
}
})
return {optimisticProduct};
}

onSucess: (product, variables, context) => {


[Link]<Product[]>(
['products',{filterKey: [Link]}],
(old) => {
if(!old) return [product];
return [Link]((cacheProduct) => (
[Link] === [Link]?
product:cacheProduct;
))
}
);
}
onError: (error, variables, context) => {
[Link]<Product[]>(
['products',{filterKey: [Link]}],
(old) => {
if(!old) return [];
return [Link]((cacheProduct) => (
[Link] !==
[Link]
))
}
);
}

-El context contiene lo que se retorna en el onMutation


-Variables contiene lo que enviamos como peticion
-OnSucess en para actualizar el nuevo ID y onError para limpiar del cache
el optimisticProduct

También podría gustarte