Cómo construir una aplicación React con RTK-QUERY
Es imposible ser un desarrollador front-end que trabaja con React y no haber oído hablar de redux en su vida. La mayoría de las empresas utilizan redux en su base de código y conocer los conceptos básicos se ha convertido en una de las esencias de ser un Frontender. Hay muchas discusiones sobre su uso o no en su producto. La verdad es que nunca se puede encontrar una herramienta perfecta para todos los proyectos. Debe decidir qué herramientas se adaptan mejor a sus objetivos y producto. Aunque hay algunos pros y contras para cada herramienta, lo más importante es el equilibrio entre los beneficios y las desventajas de la herramienta para USTED .
RTK Query es una poderosa herramienta de recuperación y almacenamiento en caché de datos. Está diseñado para simplificar los casos comunes de carga de datos en una aplicación web, eliminando la necesidad de escribir manualmente la lógica de obtención y almacenamiento en caché de datos.
Si está utilizando redux, especialmente redux-toolkit , ya sabe que rtk-query viene como una dependencia integrada con él. Hay muchas herramientas similares, como react-query, pero cuando usas redux-toolkit y ya tienes rtk-query en tu paquete, ¿por qué no usarlo? Algunos beneficios de trk-query son:
- Es completamente compatible con redux.
- Escrito en TypeScript
- Mejora su capa de servicio para que sea más reutilizable y lleva su proyecto con ganchos generados automáticamente al siguiente nivel
- Es rastreable y observable a través de redux-devtools
- Tiene un muy buen comportamiento de almacenamiento en caché.
Requisito previo
- Debes saber Reaccionar
- Debe conocer los conceptos de redux y redux-toolkit y querer usarlos en su proyecto
- Tener experiencia con TypeScript es una ventaja, pero simplemente puede eliminar partes de TS de los códigos y funciona con JavaScript para usted :)
¿Como funciona?
Como mencioné anteriormente, rtk-query es una herramienta de búsqueda que brinda toneladas de funciones para hacer que su proyecto sea más limpio y reutilizable. Sus servicios se pueden crear en forma de puntos finales y consultas mediante el uso de createApi , que es completamente similar a createReducer . Genera ganchos para tus consultas y puedes usarlos fácilmente en tus componentes. Ya no necesitará estados de carga, manejo de errores, funciones de recuperación, recuperación previa con useEffect y analizadores de datos porque rtk-query se encargará de eso por usted.
De hecho, las consultas son las piezas más pequeñas de sus servicios que pueden ser GET o POST para obtener o enviar datos al servidor. Todas las consultas relacionadas con una entidad se empaquetan en un punto final creado por createApi . Al final, su capa de servicio es una combinación de diferentes puntos finales que incluyen sus propias consultas.
rtk-query está utilizando la API de obtención de JavaScript. Pero puede configurarlo para usar axios o graphql. Además, envuelve sus consultas por inmersión , por lo que la mutación de datos ya no es una preocupación.
Construyendo los cimientos
Puede elegir CUALQUIER herramienta y configuración que desee para este proyecto. Usaré Vite, pero no importa si te gusta más CRA o prefieres configurar tu propio modelo. Después de crear nuestro proyecto React, debemos instalar redux-toolkit + axios y configurarlo:
npm install @reduxjs/toolkit react-redux axios
// src/services/api.ts
const axiosBaseQuery =
(): BaseQueryFn<AxiosRequestConfig, unknown, AxiosError> =>
async ({ url, method, data, params }) => {
try {
Axios.defaults.baseURL = "https://jsonplaceholder.typicode.com/";
const result = await Axios({
url,
method,
data,
params,
});
return { data: result.data };
} catch (axiosError) {
const error = axiosError as AxiosError;
return {
error,
};
}
};
Usaremos las API gratuitas de JSONPlaceholder en este proyecto.
En segundo lugar, debemos decirle a rtk-query que use nuestra función de consulta personalizada en lugar de la API de búsqueda de JS. Es simplemente factible al pasar nuestra función a createApi .
// src/services/api.ts
export const apiService = createApi({
baseQuery: axiosBaseQuery(),
endpoints: () => ({}),
});
Finalmente, necesitamos agregar apiService a la tienda redux y agregar la tienda a nuestra aplicación:
// src/store/store.ts
export const store = configureStore({
reducer: {
[apiService.reducerPath]: apiService.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiService.middleware),
});
// src/main.tsx
<Provider store={store}>
<App />
</Provider>
Construyendo nuestro primer servicio
Comenzamos con el punto final GET para recuperar la lista de publicaciones del servidor. Simplemente podemos usar la API injectEndpoint de rtk-query para crear nuestros puntos finales y agregarlos a nuestra capa de servicio base.
// src/services/posts.ts
// Interface of JSONPlaceholder posts
export interface Post {
id: number;
userId: number;
title: string;
body: string;
}
export const postService = apiService.injectEndpoints({
endpoints: (build) => ({
// query<ResultType, QueryArg>
getPosts: build.query<Post[], null>({
query: () => ({ method: "GET", url: "posts" }),
}),
}),
});
// Auto-generated hooks
export const { useGetPostsQuery } = postService;
Luego, rtk-query crea ganchos para que obtenga estas consultas fácilmente. Puede pasar más configuraciones a sus constructores de consultas como transformResponse , que no cubrimos porque están fuera del alcance de este artículo.
Usemos nuestro primer servicio
Ahora es el momento de utilizar nuestro servicio. rtk-query generó el gancho useGetPostsQuery para nosotros. Este gancho devuelve un objeto que consta de algunos valores útiles para usar. Como estado de carga, error, datos devueltos y función de recuperación.
- Estado de carga: Será verdadero cuando ejecutemos esta consulta en nuestro componente.
- Objeto de error: si nuestra consulta falla, se devolverá un objeto de error; de lo contrario, es nulo .
- data: Nuestros datos devueltos. Es nulo hasta que nuestra consulta se ejecute correctamente .
- función de recuperación: podemos usar esta función para volver a ejecutar la consulta cuando lo necesitemos. Por ejemplo, en caso de que queramos tener un botón de “Intentar de nuevo” o actualizar.
// src/components/PostList.tsx
const PostList: React.FC<unknown> = () => {
const { data: posts, isLoading, error, refetch } = useGetPostsQuery(null);
if (isLoading) {
return <div>Loading posts...</div>;
}
if (error) {
return <ErrorBanner error={error as AxiosError} refetch={refetch} />;
}
return (
<div>
<h2>Posts</h2>
<div>
{posts?.map((post) => (
<div className="postItem">
<h4>{post.title}</h4>
<p>{post.body}</p>
</div>
))}
</div>
</div>
);
};
export default PostList;
Para avanzar más, cubramos también una consulta de mutación. Queremos crear una publicación utilizando un formulario que obtenga un título y un cuerpo de los usuarios. Comencemos con la consulta en sí:
// src/services/posts.ts
export interface CreatePostDto {
title: string;
body: string;
}
export const postService = apiService.injectEndpoints({
endpoints: (build) => ({
// query<ResultType, QueryArg>
getPosts: build.query<Post[], null>({
query: () => ({ method: "GET", url: "posts" }),
}),
// We use mutation for POST endpoints
createPost: build.mutation<Post, CreatePostDto>({
query: (data) => ({
method: "POST",
url: "posts",
// We pass static userId to simplify this part
data: { userId: 1, ...data },
}),
}),
}),
});
// Auto-generated hooks
export const { useGetPostsQuery, useCreatePostMutation } = postService;
- Como queremos agregar algunos datos con el método POST , usamos build.mutation en lugar de build.query .
- Especificamos una nueva interfaz para los argumentos de nuestro punto final y pasamos los datos correspondientes a nuestra solicitud de axios.
// src/components/PostForm.tsx
const PostForm: React.FC<unknown> = () => {
const [title, setTitle] = useState<string>("");
const [body, setBody] = useState<string>("");
const [createPost, { isLoading }] = useCreatePostMutation();
const submitForm = async (e: FormEvent) => {
e.preventDefault();
try {
await createPost({ title, body });
} catch (e) {
console.log(e);
}
};
return (
<form onSubmit={submitForm}>
<input
name="title"
type="text"
placeholder="Title"
value={title}
onChange={(e) => setTitle(e.currentTarget.value)}
/>
<textarea
name="body"
placeholder="Body..."
rows={5}
value={body}
onChange={(e) => setBody(e.currentTarget.value)}
/>
<input
type="submit"
value={isLoading ? "Wait..." : "Submit"}
disabled={isLoading}
/>
</form>
);
};
export default PostForm;
Envuélvelo
Hemos cubierto los conceptos básicos más importantes de rtk-query. Vimos cómo podemos crear nuestros servicios y puntos finales de forma modular y cómo usar fantásticos ganchos generados automáticamente en nuestros componentes. Más adelante, publicaré artículos de seguimiento que explican funciones y conceptos más avanzados de rtk-query como almacenamiento en caché , recuperación de configuración , transformación de datos, etc.
El código base completo de todo lo que hemos cubierto se publica en este repositorio y se implementa en esta página .
Si tienes alguna recomendación o sugerencia, no dudes en preguntarme por mi correo privado o agregar comentarios y si te gustó este artículo, ¡ no olvides aplaudir!
Más contenido en PlainEnglish.io .
Regístrese para recibir nuestro boletín semanal gratuito . Síganos en Twitter , LinkedIn , YouTube y Discord .
¿ Interesado en escalar su inicio de software ? Visita Circuito .

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































