[TIL] React Query 가독성과 유지보수를 고려해 작성하기

곽재훈·2024년 7월 1일
3

React Query 코드 가독성과 유지보수를 고려해서 작성하기

그동안 react query를 사용할 때 useQuery를 익명 함수로 한 번 더 묶어서 hook으로 분리해 사용하고는 했지만, queryKey등을 한 번 더 분리하여 관리하는 방법이 있길래 오늘 연습해봤다.

기존에 사용하던 방법

export const useProducts = () => useQuery({
	queryKey: ["products"],
  	queryFn: () => api.products.getProducts(),
})
//
export const useProduct = (id: number) => useQuery({
    queryKey: ["products", id],
    queryFn: () => api.products.getProduct(id),
});

이번에 시도하는 방법

const queryKeys = {
  products: ["products"] as const,
  product: (id: number) => [...queryKeys.products, id] as const,
};
//
const queryOptions = {
  products: () => ({
    queryKey: queryKeys.products,
    queryFn: () => api.products.getProducts(),
  }),
  product: (id: number) => ({
    queryKey: queryKeys.product(id),
    queryFn: () => api.products.getProduct(id),
  }),
};
//
export const useProducts = () => {
  return useQuery(queryOptions.products());
};
export const useProduct = (id: number) => {
  return useQuery(queryOptions.product(id));
};
// api.ts
import axios, { AxiosInstance } from "axios";
import { BrandsAPI } from "./api.brands";
import { ProductsAPI } from "./api.product";

const BASE_URL = "https://api.ballang.yoojinyoung.com";

const client = axios.create({
  baseURL: BASE_URL,
  headers: {
    "Content-Type": "application/json",
  },
  withCredentials: true,
});

class API {
  private client: AxiosInstance;
  public products;
  public brands;

  constructor() {
    this.client = client;
    this.products = new ProductsAPI(this.client);
    this.brands = new BrandsAPI(this.client);
  }
}

const api = new API();

export default api;

// api.products.ts

import { AxiosInstance } from "axios";

export class ProductsAPI {
  private client: AxiosInstance;

  constructor(client: AxiosInstance) {
    this.client = client;
  }

  async getProducts() {
    const response = await this.client.get("/products");
    return response.data;
  }
  async getProduct(id: number) {
    const response = await this.client.get(`/products/${id}`);
    return response.data;
  }
}

// query.products.ts

import { useQuery } from "@tanstack/react-query";
import api from "../api/api";

const queryKeys = {
  products: ["products"] as const,
  product: (id: number) => [...queryKeys.products, id] as const,
};

const queryOptions = {
  products: () => ({
    queryKey: queryKeys.products,
    queryFn: () => api.products.getProducts(),
  }),
  product: (id: number) => ({
    queryKey: queryKeys.product(id),
    queryFn: () => api.products.getProduct(id),
  }),
};

export const useProducts = () => {
  return useQuery(queryOptions.products());
};

export const useProduct = (id: number) => {
  return useQuery(queryOptions.product(id));
};
profile
개발하고 싶은 국문과 머시기

0개의 댓글

관련 채용 정보