본문 바로가기
4주차

Tanstack Query

by primav 2025. 5. 13.

안녕하세요 웹 YB 권새봄입니다!

저번 프로젝트에서 Tanstack Query를 사용해봤는데, 어떤 점이 장점인지에 대해 잘 모르고 사용했던 것 같아 이번 기회에 자세히 알아보고자 글을 작성해봤습니다 😊

 

TanStack Query 공식 문서 바로가기: https://tanstack.com/query/latest/docs/framework/react/overview

 

Overview | TanStack Query React Docs

TanStack Query (formerly known as React Query) is often described as the missing data-fetching library for web applications, but in more technical terms, it makes fetching, caching, synchronizing and...

tanstack.com

 

📌 TanStack Query란?

React 기반의 웹 애플리케이션에서는 서버에서 데이터를 가져와 화면에 렌더링하는 일이 매우 빈번합니다. 이 과정에서 데이터 패칭(Fetching), 캐싱(Caching), 상태 동기화(Synchronization), 업데이트(Update) 등의 작업을 매번 수동으로 처리하다 보면 코드가 길어지고 복잡해지며, 유지보수도 어려워질 수 있습니다.

TanStack Query는 이러한 서버 상태 관리를 훨씬 더 직관적이고, 간편하며, 효율적으로 만들어 주는 강력한 도구입니다. 특히, 복잡한 데이터 흐름 속에서도 일관된 상태를 유지하고, 네트워크 요청을 최소화하며, 사용자 경험(UX)을 향상시키는 데 매우 중요한 역할을 합니다.

TanStack Query의 주요 장점

  • 간편한 데이터 관리
    데이터를 가져오고, 캐싱하고, 동기화하고, 갱신하는 로직을 간소화
  • 실시간 업데이트 및 자동 동기화
    서버와 클라이언트 간의 데이터 불일치를 자동으로 해결하여 항상 최신 상태를 유지
  • 강력한 캐싱 기능
    동일한 요청에 대해 캐시를 활용함으로써 불필요한 API 호출을 줄여 성능을 향상
  • 로딩, 에러, 성공 상태 자동 관리
    서버 상태를 직접 관리할 필요 없이 상태에 따른 처리를 간편하게

📌 Tanstack Query 사용 이유

Tanstack Query 사용 전 : 기존 데이터 패칭 코드

  1. Fetching 코드 작성
const getData = async () => {
    const data = await fetch("http://naver.com/user/saebom")
                    .then((response) => response.json());
    return data;
}
  1. 데이터를 담아 둘 상태 생성
  2. const [data, setData] = useState();
  3. useEffect를 이용해 컴포넌트 마운트 시 데이터 Fetching 후 상태 저장
  • 하나의 데이터를 패칭함에 있어 작성되는 코드 라인 수가 많음
  • useEffect를 많이 사용하기 때문에 발생할 수 있는 side effect로 인해 코드의 흐름 파악이 어려움
  • 한 페이지내에서 데이터 패칭을 하는 로직이 여러개가 된다면 관리하기가 어려움!!!
  • useEffect(()=> { getData() .then((res) => setState(res)) .catch((err) => { console.log(err.response.data) }); }, []);

Tanstack Query 사용

  1. Fetching 코드 작성
const getData = async () => {
    const data = await fetch("http://naver.com/user/saebom")
                    .then((response) => response.json());
    return data;
}
  1. 데이터를 Fetching 및 상태 저장
  • 코드 라인 수 감소
  • useEffect 사용 안하므로 코드 흐름 파악하기 쉬움
  • const { data } = useQuery(["data"], setData);

📌 Query & Mutation

🎯 Query

데이터를 가져오고 캐싱하며, GET으로 받아오는 대부분의 API에서 useQuery() 함수를 사용합니다.

const { data } = useQuery(
      queryKey,
      queryFunction,
      options,
)
  • 첫번째 인자 : 응답 데이터의 Unique Key - 응답 데이터를 캐싱할 때 사용됩니다.
  • 두번째 인자 : Promise 를 반환하는 함수 - 쿼리 요청을 수행하기 위한 fetch, axios
  • 세번째 인자 : useQuery에 사용되는 옵션을 지정하는 객체
    • data
    • error
    • isFetching, isLoading, isSuccess

🎯 Mutation

데이터를 업데이트하고 캐시를 업데이트 할 수 있으며, 데이터 생성, 수정, 삭제 용으로 사용되며, POST, PUT, DELETE 요청시에 사용합니다.

const { mutate } = useMutation(
      mutationFn,
     options,
);
  • 첫번째 인자 : Promise를 반환하는 함수 - fetch, axios
  • 두번째 인자 : useMutation에 사용되는 옵션을 지정하는 객체

📌 데이터 캐싱

캐싱을 활용하여 불필요한 API 호출을 줄임으로써 전체적인 애플리케이션 성능을 향상 시킬 수 있습니다.

🎯 staletime

캐시된 데이터의 유효 기간을 나타내는 옵션으로, 호출한 데이터는 리액트 쿼리 자체적으로 저장하는데, staletime의 기본 값은 0으로 설정되어 있어 데이터가 한번 캐시되면 즉시 만료되고 다시 요청됩니다.

이 값을 조정해서 데이터를 일정 시간 동안 캐시로 사용하고, 그 이후에만 다시 요청하도록 할 수 있습니다.
➡️ 데이터의 유통기한 !!

자주 변경되지 않는 데이터의 경우 캐시된 데이터를 사용함으로써 불필요한 네트워크 요청을 줄이고, 애플리케이션의 성능을 향상시킬 수 있습니다.

const { data } = useQuery(['data', getServerData,{
  staletime: 10 * 60 * 1000;
})

🎯 cachetime

cachetime은 캐시된 데이터가 얼마나 오랫동안 메모리에 유지될지를 나타내는 옵션으로, 이 값을 설정하면 캐시된 데이터가 일정 시간 동안 메모리에 유지된 후 자동으로 삭제됩니다.

데이터가 일정 기간 동안 메모리에 남아 있게 함으로써 같은 데이터를 다시 요청할 때 캐시에서 가져오기 때문에 성능을 향상 시킬 수 있습니다.

const { data } = useQuery(['data', getServerData], {
  cachetime: 30 * 60 * 1000, // 30분
})

차이점

비교 항목 staleTime (데이터 유효 기간) cacheTime (캐시 유지 기간)
기본값 0 (즉시 만료) 5분
역할 데이터가 신선한지(Stale 상태) 판단 캐시된 데이터가 메모리에 얼마나 남아 있을지 결정
데이터 요청 신선할 때는 요청 X 만료되면 다시 요청 가능 (단, cacheTime 내에서는 캐시 사용 가능)
네트워크 요청 Stale 상태가 되면 refetch 가능 cacheTime이 지나면 데이터 삭제 후 다시 요청 필요

💡 결론

staleTime은 데이터가 신선한지(Stale인지) 결정
cacheTime은 캐시가 메모리에 얼마나 남아 있을지 결정

즉, staleTime은 데이터를 언제 새로 요청할지 결정하고, cacheTime은 캐시된 데이터를 언제 삭제할지 결정합니다!

  • 자주 변하지 않는 데이터
    staleTime을 길게 설정하여 불필요한 네트워크 요청 방지
  • 재방문 시에도 캐시된 데이터를 유지하고 싶다면
    cacheTime을 길게 설정하여 성능 최적화