useQuery 사용법

2025. 11. 12. 12:08Coding Study/Tanstack Query

 

1. React 에서의 일반적인 데이터 패칭 방법

 1) 데이터를 받아오는 비동기 함수를 작성

export async function fetchMovieDetail(id: string) {
  const options = {
    method: 'GET',
    headers: {
      accept: 'application/json',
      Authorization: `Bearer ${API}`,
    },
  }
  const response = await fetch(
    `https://api.themoviedb.org/3/movie/${id}?language=ko`,
    options
  )

  if (!response.ok) {
    throw new Error('영화 정보를 불러오지 못했습니다.')
  }

  const data: MovieDetail = await response.json()

  return data
}

 

 

 2) 비동기 함수의 응답 결과를 담을 상태를 정의하고, 함수를 작성하여 비동기 함수의결과 값과 에러처리 및 로딩처리를 한 후 useEffect 내에서 실행 하게 된다.

const [ movieDetail, setMovieDetail ] = useState<MovieDetail[]>([])
const [ isLoading, setIsLoading ] = useState(false)
const [ error, setError ] = useState()

const fetchData = async (id) => {
   setIsLoading(true)                          //(2) fetch 전 로딩...
   try{
     const data = await fetchMovieDetail(id)   //(3) 데이터를 받아와서
     setMovieDetail(data)                      //(4) 상태에 저장
    } catch (error) {                          //(5) 에러처리
     setError(error)                           
    } finally {
     setIsLoading(fals)                        //(6) 로딩 종료
    }
   }
 
  useEffect(()=>{                              //(1) useEffect 에서 fetch 함수 실행
  	fetchData(movieId)
  },[movieId])

 

3)  상기 코드의 문제점 및 Tanstack Query 를 도입해야 하는이유

   • 상태관리가 복잡 하고 보일러 플레이트가 많다

      • 데이터 하나 조회하는데 3개의 상태와 useEffect에 try - catch - finally 구문까지 써야 한다.

      • 하나가 아니라 다름 여러 API를 호출 한다면 코드가 기하급수적으로 길어진다.

  • 캐싱기능 부재

      •  이미 불러온 데이터 재사용 불가, 뒤로가기 후 재 진입 시 또다시 로딩 발생

      •  다른 컴포넌트에서 똑같은 데이터를 가져오려고 할때 다시 API를 호출하게 된다.

  • 경쟁상태 처리 안됨

      •  상황 : 사용자가 movieId 1번을 클릭하고, 로딩중 바로  movieId 2번을 클릭 시

      •  현상 : 요청1( id -1 ) 이후 요청2(id - 2) 를 했는데 요청 2가 먼저 완료 되고 요청 1이 나중에 완료

      •  결과 : 이경우 요청 1이 요청 2의 자료를 덮어 씌우게되어 심각한 버그가 발생

  • 최신데이터 동기화 어려움

      •  현재 코드로는 "새로 고침"을  누르지 않는 한 데이터가 갱신되지 않는다.

      •  사용자가 탭을 닫지않고 다른탭으로 갔다가 돌아오거나, 오랫동안 페이지를 켜두었을 때 데이터가 구식이 될 수 있다.

  • 에러처리 및 재시도 로직 부재

      • API 요청이 한번 실패하면 곧바로 에러 화면이 뜬다.

      

2. Tanstack Query 에서는 

 1) 여러 상태 관리가 필요 없이 data, isLoading, isError 등 바로 쓸 수 있게 상태를 반환해서 준다.

 2) 기본 캐싱 시간은 0초 지만 option 으로 staleTime을 ms 단위로 지정이 가능하다.

 3) 경쟁상태 처리를 query key 를 바탕으로 자동으로 처리한다.

 4) Window Focus 시나 통신연결이 끊긴후 연결될 시 자동으로 최신데이터 갱신

 5) 네트워크 실패 시 기본값으로 3회 재시도

 

3. useQuery를 사용한 데이터 패칭 방법

 1) 비동기 함수(fetchMocieDetail) 는 위와 동일 하다.

 

 2) useQuery 라는 훅을 통해서 data와 Loading 값을 반환 받아서 사용할 수 있다.

     위에서 useEffect 로 비동기 함수를 실행 하는 방법 보다 좀더 간결하게 패칭데이터를 불러올 수 있다.

const { data: movieDetail, isPending: isLoading } = useQuery({
    queryFn: () => fetchMovieDetail(id),
    queryKey: ['movieDetail', id],
    enabled: !!id,
  })

 * queryFn : 실행 할 비동기 함수를 넣어 준다.

 * queryKey : 쿼리 키 값으로 비동기 함수의 값을 캐싱하여 저장한다. 이를 통해서 캐싱된 값을 가져와서 쓸 수 있다. 

 * enabled : 값이 true 일 경우에만 queryFn 을 실행한다. ( 위에서는 id 의 값이 있을 경우에만 실행 )

'Coding Study > Tanstack Query' 카테고리의 다른 글

Tanstack Query 설정  (0) 2025.11.12