React-Query 프로젝트에 적용하기

해준박·2023년 11월 7일
0
post-thumbnail
post-custom-banner

기술적용이유

  • 코드유지보수에 효율적
  • 캐싱메모리를 사용하여 데이터를 재사용해서 빠른 액세스 가능
  • fetch후 변경된 데이터가 있을 시 자동으로 컴포넌트 리렌더링
  • 다른 사람들도 많이 쓰니까

처음 우리가 하고싶었던것은 물건들이 올라와있는 메인페이지에서 누군가가 업로드 할 경우 데이터를 감지하고 리렌더링 하는 것이었다.

이걸 찾다가 react-query가 가능할 것 같았고, 원하는대로 구현이 가능했다.


useQuery

// api/productData.ts
const getProducts = async () => {

  const res = await axios.get(`${process.env.REACT_APP_EXPRESS_URL}/api/product`);

  const data: IProduct[] = sortProducts(res.data.products.reverse());

  return data;
};

export { getProducts };

api 파일을 따로 만들었다. 분리 할 수록 파일은 많아지지만 유지보수에 용이하고 또한 재사용할 때도, 효율적이다.

useQuery를 이용할 때는 promise값을 반환해야한다. 그래서 위 코드를 보면 상품의 데이터를 반환한다

// productsList.tsx

const { isLoading, data } = useQuery(["Products"], getProducts, {
    staleTime: 3000, // fresh 시간
    refetchInterval: 200000, // 자동 refetch 시간
    refetchIntervalInBackground: true, // 백그라운드에서도 refetch
  });
  const products = data || [];

정보를 불러오는 화면이라 useQuery를 이용해서 getProducts를 불러온 다음
3가지 옵션을 추가해주었다.

  • staleTime - 3초의 fresh를 주어 3초간은 기본적인 refetch가 일어나지 않도록 설정
  • refetchInterval - 3분마다 자동으로 refetch
  • refetchIntervalInBackground - 백그라운드상태에서도 refetch 일어나게

이렇게 페이지를 불러오는 단계는 간단하게 마무리했다.

이 다음으로는 useMutaion을 이용해 post를 사용해보자

useMutaion

기존 api를 이용하여 불러오는 코드를 옮겼다. 삭제 후 유저 업데이트를 해주기 위해 updateUser를 프로미스 값을 두었음

// api/productData.ts

const deleteProduct = async (id: string) => {
  const { updateUser } = await (
    await axios.delete(`${process.env.REACT_APP_EXPRESS_URL}/api/product/${id}/delete`, { withCredentials: true })
  ).data;
  return updateUser;
};

const updateProduct = async (id: any) => {
  await axios.post(
    `${process.env.REACT_APP_EXPRESS_URL}/api/product/${id}/update`,
    { product_state: true },
    { withCredentials: true }
  );
};

useMutation은 기존 비동기 함수를 래핑하여 사용 할 수 있는데

나는 mutate 메소드를 이용해 mutation함수를 호출하였고, 성공적으로 받아왔을 경우 콜백으로 onSuccess 호출하여 다음 작업을 수행했다.

const deleteProductMutaion = useMutation((id: any) => deleteProduct(id), {
    onSuccess: (updateUser: any) => {
      setUserInfo(updateUser);
      navigate("/");
    },
  });

  const updateProductMutaion = useMutation((id: any) => updateProduct(id), {
    onSuccess: () => {
      navigate("/");
    },
  });

.
.
.

<S.ProductDetailBtn onClick={() => deleteProductMutaion.mutate(product._id)}>삭제하기</S.ProductDetailBtn>
<S.ProductDetailBtn onClick={() => updateProductMutaion.mutate(product._id)}>판매완료</S.ProductDetailBtn>

간단하게 사용했지만 UI적으로도 더 활용할 수 있어서 추후에 기능을 더 추가할수 있을것 같다

profile
기록하기
post-custom-banner

0개의 댓글