React Query 공부 (6) custom-hook

JunSeok·2023년 1월 30일
0

react-query

목록 보기
6/11
post-thumbnail

custom-hook

작은 앱이라면 상관없지만 큰 앱을 만들 때는 custom-hook을 사용해보자
공식Docs

장점

  1. 여러 개의 컴포넌트에서 액세스 가능
  2. key 값이 섞일 위험 없다.
  3. 변경 사항 있을 경우 hook 하나만 변경하면 끝

queryClient 분리 및 에러 핸들링

처음에는 보통 App.tsx파일에 queryClient를 생성하고 적용하지만
앱이 커지면 커질수록 분리하는 것이 좋다.
그리고 에러 핸들링을 이 queryClient.tsx에서 해준다.

에러 메시지를 화면에 보여줄 UI로 차크라 UI를 사용했다.
차크라 UI

// queryClient.tsx
import { QueryCache, QueryClient } from 'react-query';
import { createStandaloneToast } from '@chakra-ui/react';

const toast = createStandaloneToast();

const queryErrorHandler = (error: unknown) : void => {
	const title = error instanceof Error ? error.message : 'error connecting to server'
    toast({ title, status: 'error', variant: 'subtle', isClosable: true })
}

// default option으로 에러 설정을 하게 되면 개별 쿼리에 적용되지만, 쿼리캐시에 에러 설정을 함으로써 모든 재시도가 실패한 뒤에 에러 핸들러가 실행된다.
export const queryCleint = new QueryClient({
 	queryCache: new QueryCache({
    	onError: queryErrorHandler
    }) 
});

custom-hook 예시

지금 개인 프로젝트에서 사용중인 useQuery custom hook의 예시이다.
이렇게 만들어놓으면, 이 데이터가 필요한 컴포넌트에서 useGetGenreData 함수만 import해서 사용하면 된다!
매우 편리하다.

// GenreData.tsx
import { AxiosError, AxiosResponse } from "axios";
import { useQuery } from "react-query";

import { apiInstance } from '../../apis/setting'
import { queryKeys } from "../constants";

export const getUpComing = (page: any) => apiInstance.get(`/movies/upComing/${page}`, {
    withCredentials: true
})

const useGetUpComing = (page: any) => {
    const queryFn = () => getUpComing(page)
    return useQuery<AxiosResponse<any>, AxiosError>([queryKeys.upComing, page], queryFn)
}

export default useGetUpComing

query key 관리 파일

위 예시 코드에서 queryKey를 import하여 사용중인 모습을 볼 수 있다.
useQuery에 필요한 query key는 string 타입으로 쓰기 때문에 따로 query key를 관리하는 파일을 만드는 것이 좋다.
이렇게 모아놓으면 query key를 수정하기도 편하며, 관리하기 편하다.
그래서 바로 개인 프로젝트에 적용시켜서 사용하고 있는데 깔끔하니 좋다!

// constants.ts
export const queryKeys = {
    feedData: "feedData",
    feedSearchData: "feedSearchData",
    hitFeed: "hitFeed",
    postCommentData: "postCommentData",
    postData: "postData",
    actorSearch: "actorSearch",
    genreData: "genreData",
    movieSearch:"movieSearch",
    popularMovie:"popularMovie",
    ThemeLikeCheck: "themeLikeCheck",
    themeMovie: "themeMovie",
    upComing: "upComing",
    NotiData: "notiData",
    userImage: "userImage",
    userLiked: "userLiked",
    userPosts: "userPosts",
}
profile
최선을 다한다는 것은 할 수 있는 한 가장 핵심을 향한다는 것

0개의 댓글