Cómo construir una aplicación React con RTK-QUERY

Mar 08 2023
Una guía para principiantes para escribir consultas 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.
Foto de Fahim Muntashir en Unsplash

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

  1. Debes saber Reaccionar
  2. Debe conocer los conceptos de redux y redux-toolkit y querer usarlos en su proyecto
  3. 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.

Gráfico de capa de servicios y componentes

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;
    

    Lista de publicaciones

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;

  1. Como queremos agregar algunos datos con el método POST , usamos build.mutation en lugar de build.query .
  2. 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 .