본문 바로가기

TIL

TIL 23.09.06 react-query 리팩토링

중간발표가 끝나고 전체적인 UI를 반응형으로 변경하려고 한다.. 그 전에 정말로 해야될 것은 리팩토링 이었음.

supabase 를 컴포넌트에 그대로 갖다 쓴 죄로... 이번에 typeScript + react-query 콜라보로 리팩토링 작업을 했다.

단순히 정보를 받아오고 갱신하는 건 괜찮은데, 그밖에 내가 추가동작을 해야하는 것들 (좋아요) 같은것들은 DB 설계의 중요성도 뼈저리게 느끼게 만들었다. 

같은 조 분께서 supabase 로 타입정보도 잘 불러와주시고, auth 훅도 만들어주셔서 남발하는 코드 없이, 상대적으로 편하게 작업할 수 있었다.

 

오늘 한 작업을 간단하게 요약하면,

오늘은 한 페이지에서 다양한 제품의 좋아요 숫자를 업데이트 하는 로직을 react-query로 리팩토링했다. 

 

일단 물품 조회하는 로직을 api 로 빼주고

// 물품 조회

export const getProducts = async (): Promise<Product[]> => {
  try {
    const { data: products } = await supabase.from("product").select("*");
    return products || [];
  } catch (error) {
    throw error;
  }
};

 

다음처럼 제품을 가져오면서 쿼리키를 지정해준다.

  // 현재 제품 가져오기
  const {
    data: products,
    isLoading,
    isError,
  } = useQuery<Product[]>(["product"], getProducts);

 

좋아요 숫자 추가와 같은 것들은, product 안의 필드에 있었기 때문에, 다음처럼 숫자를 업데이트해주고

 

// 좋아요 숫자 추가
export const plusLikeCount = async (plusLike: ProductType) => {
  const { error } = await supabase
    .from("product")
    .update({ like_count: plusLike.like_count! + 1 })
    .eq("id", plusLike.id);
  if (error) return error;
};

 

기존 데이터의 쿼리무효화를 해서 바로 업데이트 했다. (사실 supabase fetch 처럼 느림.)

 

 const plusProductLikeMutation = useMutation(plusLikeCount, {
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["product"] });
    },
  });

 

이제 여기에 onSuccess 대신에 onMutation, 에러에 대비한 롤백 등을 이용한, 낙관적 업데이트 방식을 적용하면 된다. 🥹 

사실 좋아요 숫자는 이렇게 올렸는데, 좋아요 색깔을 변경을 해야했다. 데이터가 여러개라서 어떻게 해야할까 고민하던중에, 쿼리키를 지정을 해줘도 그 데이터를 조건문(유저가 로그인했을때)을 걸고 사용해야 먹히기 때문에 데이터를 가져오기가 너무 난감했다... 몇시간을 붙잡고 있었는데..

 

그래서 로그인한 상태에서 버튼 누르면 state 이용해서, 바로 하트색이 업데이트 되게 만들었다. 아마 이게 낙관적 업데이트 느낌일 것 같다.

 

1. 하트 누르면 바로 변하는 UI => 낙관적 업데이트 적용

2. 그에 반해 조금씩 느리게 바뀌는 숫자 => 미적용

 

점점 더 배우고 있는 것 같다. 리팩토링 화이팅 !!