처음 우리가 하고싶었던것은 물건들이 올라와있는 메인페이지에서 누군가가 업로드 할 경우 데이터를 감지하고 리렌더링 하는 것이었다.
이걸 찾다가 react-query가 가능할 것 같았고, 원하는대로 구현이 가능했다.
// 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가지 옵션을 추가해주었다.
이렇게 페이지를 불러오는 단계는 간단하게 마무리했다.
이 다음으로는 useMutaion을 이용해 post를 사용해보자
기존 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적으로도 더 활용할 수 있어서 추후에 기능을 더 추가할수 있을것 같다