¿Qué es React Query?
React Query es una biblioteca utilizada para trabajar con solicitudes asíncronas, diseñando el concepto de estado del servidor para el desarrollo de React, con una configuración inicial simple y sin necesidad de personalización.
En resumen, react-query es una biblioteca que surgió con el objetivo de facilitar la forma en que manejamos la búsqueda. Normalmente, en React, cuando queremos realizar un fetch, no podemos hacerlo de forma directa y sencilla y se hace necesario crear una estructura para sincronizar, pegar errores y actualizar el componente, o esto muchas veces implica no utilizar React Hooks y bibliotecas para la gestión estatal. Otras bibliotecas que funcionan con administración de estado terminan haciendo la aplicación más compleja y con código repetitivo. Con este problema vino la biblioteca de consulta de reacción, que simplifica las actividades de búsqueda, captura y sincronización.
Sin React Query, el componente se vería así:
// Importamos React y los hooks
import React, { useState, useEffect } from 'react;
// Creamos un component funcional
function MyComponent() {
// Estado remoto que guardará la fecha después del fetch
const [ data, setData ] = this.useState({});
// Estado que almacenará el estado de la solicitud
const [ status, setStatus ] this.useState('');
// Estado que guardará el mensaje de error
const [ errMsg, setErrMsg ] this.useState('');
// El useEffect sirve para controlar el ciclo de vida y obtener la fecha al crear el componente
useEffect(() => {
// Creamos la función que hará el fetch
const fetchData = async () {
setStatus("loading");
fetch(URL)
.then(result => result.json())
.then(data => {
// Después de obtener la fecha decodificada, la almacenamos en estados remotos
setData(data)
setStatus("success");)
}
.catch(error => {
setStatus("failed");
setErrorMsg(e.msg);
});
}
}
fetchData();
}, []);
};
1) Importamos los hooks y React.
2) Creamos el componente funcional.
3) Usamos useEffect para realizar la solicitud al principio del ciclo de vida del componente.
4) Creamos estados remotos que almacenarán el contenido de la recuperación, el estado y el mensaje de error, si lo hubiera.
5) Creamos una función asíncrona que es responsable de decodificar, almacenar en estado global y detectar errores.
6) Llamamos a la función creada.
Claramente usamos demasiadas líneas de código, se usaron demasiados recursos y tenemos poco control de la solicitud.
Cuando usamos React Query, el código se ve así:
// Importamos el hook para acceder a las funcionalidades
import { useQuery } from ‘react-query’;
function Example() {
// Nombramos el repositorio del servidor y accedemos a las propiedades
const { isLoading, error, data } = useQuery('repoData', () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
)
}
1) Importamos la función useQuery.
2) Creamos el componente funcional.
3) Deconstruimos el objeto devuelto por useQuery y pasamos los parámetros a la función.
Como podemos ver, se usó mucho menos código y la sintaxis es mucho más simple, lo que también permite colocar oyentes en las solicitudes para desencadenar acciones, tener control del caché, entre varias otras características.
Estado del servidor
Antes de comenzar, es importante comprender el concepto de estado del servidor. Uno de los mayores diferenciadores de React Query es que establece que la forma anterior de manejar los datos era incorrecta. Debemos tratar el estado del servidor por separado, teniendo así el “Estado de la aplicación” y el “Estado del servidor”. Como de costumbre, no podemos garantizar que el usuario esté viendo el estado actualizado, por lo que tiene más sentido tratarlo por separado, lo que permite hacer cosas como obtener datos del servidor continuamente.
Primeros pasos en React Query
Primero, comencemos React Query con un enfoque más simple:
1) Crea una aplicación React:
npx create-react-app my-project-with-query
2) Ve al directorio e instala las dependencias de React Query:
cd my-project-with-query
npm install react-query react-query-devtools axios --save
3) Para el correcto funcionamiento de la biblioteca, tenemos que crear una consulta de reacción del proveedor para que podamos saber cómo otros componentes dentro del proveedor están tratando los datos del estado del servidor src/index.js:
import React from 'react';
// Importamos los componentes necesarios para el proveedor
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// Creamos el cliente para tener acceso al caché
const queryClient = new QueryClient();
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
// Envolvemos nuestros componentes en el proveedor y pasamos la propiedad del cliente que recibe el queryClient
<QueryClientProvider client={queryClient}>
<App />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</React.StrictMode>
);
// Si deseas comenzar a medir el rendimiento en tu aplicación, pasa una función.
// Para registrar resultados (por ejemplo: reportWebVitals(console.log)) o enviar a un punto final de análisis, consulta en: https://bit.ly/CRA-vitals
reportWebVitals();
En el código anterior, primero importamos QueryClientProvider. Se utiliza para crear el proveedor de consultas de React. Luego, importamos QueryClient, responsable de crear el cliente React Query, y finalmente, envolvemos nuestros componentes con QueryClientProvider.
Se recomienda usar React Query Devtools para tener una interfaz visual de la librería, para usarla importamos el componente y lo colocamos como último elemento en el React Query Provider.
4) Ahora que tenemos nuestro proveedor, podemos aplicar la misma lógica a todos los componentes insertados en este contexto. Usemos como ejemplo el archivo App.js que viene por defecto en la carpeta src.
src/Aplicación.js:
//Importamos el hook:
import { useQuery } from 'react-query';
function App() {
//Deconstruimos useQuery y pasamos los parámetros a la función:
const { isLoading, error, data } = useQuery('repoData', () =>
// O primeiro parametro nomeia a requisição e o segundo éresponsavel pelo fetch
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
)
// Si se está cargando, lo renderizamos en la pantalla.
if (isLoading) return 'Loading...'
// Si hubo un error en la solicitud, lo representamos en la pantalla.
if (error) return 'Tuvimos un error' + error.message
// Si todo va bien, renderizamos el contenido de la solicitud hasta la fecha.
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>:eyes: {data.subscribers_count}</strong>{' '}
<strong>:sparkles: {data.stargazers_count}</strong>{' '}
<strong>:fork_and_knife: {data.forks_count}</strong>
</div>
)
};
export default App;
En React Query, tenemos las famosas consultas que, en resumen, se utilizan para obtener datos del servidor y cambiar algunas configuraciones de recuperación.
Al analizar el código anterior, podemos ver que hemos deconstruido el objeto devuelto por la función useQuery para usar alguna información:
- Data: Para “obtener” la información.
- isLoading: Para verificar la carga.
- Errores: Para corroborar la existencia de errores.
Es importante recordar que existen muchas otras consultas. Sin embargo, solo comenzaremos con éstas.
En la función useQuery que importamos, podemos pasar algunos parámetros:
Query Key
Un identificador para la solicitud. Esta clave de consulta se usa para que React Query pueda controlar la solicitud de una manera única y no confundirse al realizar búsquedas duplicadas. Por ejemplo, al tener dos componentes que usan la misma clave de consulta, garantizamos que solo se realizará una búsqueda.
Función fetch
En el segundo parámetro pasamos la función que se encarga de la búsqueda, esta función devolverá una Promesa y useQuery enviará este resultado a la constante "datos".
Con eso, pudimos usar React Query. Sin embargo, todavía hay mucho más para aprovechar la biblioteca.
Configurar queries en la función useQuery
Además de las consultas utilizadas hasta ahora, podemos pasar un objeto como parámetro de useQuery y en este objeto, pasar algunas propiedades que funcionarán como una especie de configuración de recuperación. Siga el ejemplo a continuación:
src/App.js :
//Importamos el hook:
import { useQuery } from 'react-query';
function App() {
// Deconstruimos useQuery y pasamos los parámetros a la función:
const { isLoading, error, data } = useQuery('repoData', () =>
// El primer parámetro nombra la solicitud y el segundo es responsable de la búsqueda
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
) ,
{
refetchOnWindowFocus: false,
retry: 6,
refetchInterval: 1000,
onSuccess: (data) => {
console.log(data);
},
onError: (error) => {
console.log(error)
},
}
)
// Si se está cargando, lo renderizamos en la pantalla
if (isLoading) return 'Loading...'
// Si hubo un error en la solicitud, lo representamos en la pantalla
if (error) return 'Tuvimos un error' + error.message
// Si todo va bien, renderizamos el contenido de la solicitud hasta la fecha.
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>:eyes: {data.subscribers_count}</strong>{' '}
<strong>:sparkles: {data.stargazers_count}</strong>{' '}
<strong>:fork_and_knife: {data.forks_count}</strong>
</div>
)
};
export default App;
Ahora agregamos algunas consultas al objeto que cambiarán la operación predeterminada de la búsqueda, en nuestro ejemplo tenemos:
refetchOnWindowFocus
Esta propiedad se cumple de manera predeterminada y es responsable de obtenerla cada vez que el usuario sale y regresa a la pantalla de navegación. Por lo tanto, es muy útil actualizar los datos solo cuando el usuario está usando la aplicación.
retry
Sirve para intentar el fetch más de una vez, puede usarse para evitar problemas causados por errores de conexión. Viene por defecto como 3, sin embargo, también puede tomar valores booleanos como verdadero y falso. Cuando es verdadero lo intenta infinitamente hasta que tiene éxito, cuando es falso no lo intenta más de una vez. En nuestro ejemplo, se usó reintentar para garantizar que intente obtener un máximo de 6 veces antes de devolver el error.
refetchInterval
También llamado sondeo, refetchInterval es responsable de realizar la búsqueda periódicamente. En nuestro ejemplo, estamos tratando de obtenerlo cada 1 segundo. Esta propiedad se puede usar cuando necesitamos que los datos se actualicen constantemente, como, por ejemplo, una búsqueda que devuelve la hora actual.
onSuccess
En esta propiedad pasamos una función que se llamará cuando la solicitud se haya realizado con éxito, en nuestro caso, llamamos a una función anónima solo para hacer un console.log de la constante "datos".
onError
Es una propiedad que le pasamos a una función que será llamada cuando ocurra un error en la solicitud, en el ejemplo la usamos para dar un console.log de la constante “data” también.
Conclusión
Sin React Query, para asegurarnos de que el contenido obtenido se procesará tan pronto como el usuario ingrese a la página, debemos usar el ciclo de vida del componente y almacenar los datos en el estado local. Con Query, esta acción se realiza automáticamente, lo que elimina la necesidad de trabajar con el ciclo de vida de los componentes y también elimina la necesidad de usar el estado remoto, lo que mejora el rendimiento y reduce en gran medida la complejidad.
Desarrollar aplicaciones con él hizo que trabajar con asincronía fuera mucho más fácil. Incluso cuando la aplicación es más grande, la sintaxis sigue siendo corta y la experiencia del usuario es mucho más fluida. React Query fue la mejor biblioteca para manejar datos relacionados con el servidor que encontré y usaré mucho en mis proyectos futuros.
Revelo Content Network da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.