본문 바로가기
2024/TIL

[TanStackQuery] ReactQuery 개념 정리

by ye-jji 2024. 10. 20.

React Query란? 

• 리액트에서 복잡한 데이터 상태 및 비동기 작업 관리를 간편하게 처리할 수 있는 기능을 제공하는 라이브러리

• 데이터 캐싱, 리패칭, 뮤테이션 등과 같은 복잡한 작업들을 편하게 수행할 수 있게 해줌

• 자동으로 데이터를 캐싱하여 네트워크 요청을 최소화함

• 실시간 동기화를 지원하여 데이터가 변경될 때 자동으로 새로운 데이터를 업데이트함

• 쿼리를 통해 서버 요청을 효과적으로 관리할 수 있음(중복 요청 방지, 요청 취소, 재시도)

• 성숙한 생태계를 가지고 있고, 타입스크립트를 지원하고, Next.js와의 통합이 잘 되어 있으며, 비동기 작업 관리에 매우 편리함

 

React Query 주요 기능

데이터 가져오기와 캐싱: useQuery 함수를 사용 하여 데이터 불러오기, 자동 캐싱, 중복 요청 방지 가능

import { useQuery } from 'react-query';

function Component() {
  const { data } = useQuery('data', fetchDataFuction);
  // ...
}

 

자동 리페치: 데이터를 주기적으로 업데이트해야 하는 경우, refetchInterval 옵션을 사용해서 설정 가능

const { data } = useQuery('data', fetchDataFunction, {
  refetchInterval: 10000, //10sec
});

 

뮤테이션: 데이터 변경 작업(생성, 수정, 삭제)을 간단하게 수행할 때 사용 가능

import { useMutation } from 'react-query';

function Component() {
  const mutation = useMutation(creatDataFunction);
  // ...
}

 

React Query 캐싱

• 데이터를 가져와서 처음 한 번 캐싱하면, 이후 동일한 데이터에 대한 요청은 네트워크 요청을 보내지 않고 캐시된 데이터를 사용하는 것

staleTime 옵션: 캐시된 데이터의 "잘못된" 상태(stale state)를 얼마 동안 허용할지 설정하는데 사용

import { useQuery } from 'react-query';

function Component() {
  const { data } = useQuery('data', fetchDataFunction,
  {
    staleTime: 60000, //60sec
  });
  // ...
}

• 잘못된 상태란? 데이터가 업데이트되었지만, 이전에 캐싱된 데이터가 여전히 사용 가능한 상태

• staleTime은 기본적으로 0으로, 데이터가 한 번 불러와지면 다음 요청 시에는 항상 새로운 데이터를 가져옴

 

React Query 주요 함수

1. useQuery

: 데이터를 가져올 때 사용하는 함수. 데이터를 캐싱하고 자동으로 리페칭 관리. 로딩, 에러, 데이터 등을 처리할 수 있는 옵션 제공

const { isLoading, isError, data, error } = useQuery('data', fecthData)

if(isLoading) {
  return <p>Loading...</p>;
}

if(isError) {
  return <p>Error: {error.message}</p>;
}

 

• isLoading: 데이터 가져오는 중인지 여부

• isError: 데이터 가져오는 중 에러 발생 여부

• data: 성공적으로 데이터를 가져온 경우, 데이터가 포함된 변수

• error: 데이터 가져오는 중 발생한 에러 정보

 

2. useQueryClient

: 리액트 쿼리 클라이언트에 접근해서 다양한 작업 수행 가능 (캐시 조작, 캐시 데이터 작업 등)

const queryClient = useQueryClient();

// Todo 목록 가져오기
const { data: todos } = useQuery('todos', fetchTodos);

cosnt handleUpdateTodos = (id, text) => {
  //Todo 업데이트 API 호출
  
  //다른 쿼리 갱신: 'todos' 쿼리 다시 로드
  queryClient.invalidateQueries('todos');
};

 

3. useMutation

: 데이터 변경 작업 수행에 사용.

const mutation = useMutation({
  mutationFn: postTodo,
  onSuccess: () => {
    // Invalidate and refetch
    queryClient.invalidatdQueries({ queryKey: ['todos']})
  },
})

return (
  <button
    onClick={()=>{
      mutation.mutate({
        id: Date.now(),
        title: 'Study React Query',
      })
    }}
  >
    Add Todo
  </button>
)

• useMutation 호출하여 mutation 객체 생성. 해당 객체에 함께 사용할 함수 정의

• 성공 / 실패 여부 처리 가능. 데이터 업데이트 후 리페치 관리 

 

React Query 세팅 방법 & 예시

• 최상단 파일(_app.tsx)에 QueryClientProvider로 애플리케이션을 감싸고, queryClient 설정

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

//creat a client
const queryClient = new QueryClient()

function App() {
  return (
    // Provide the client to your App
    <QueryClientProvider client={queryClient}>
      <Todos />
    </QueryClientProvider>
  )
}

React Query와 Next.js

• React Query는 Next.js 프로젝트에도 유용하게 적용할 수 있음

• SSR를 사용하는 경우, getServerSideProps 혹은 SSG를 사용 하는 경우, getStaticProps와 함께 리액트 쿼리를 사용할 수 있음

• React Query로 데이터를 미리 가져와 페이지를 서버에서 렌더링 가능 

export async function getStaticProps() {
  const posts = await getPosts()
  return { props: { posts } }
}

function Posts(props) {
  const { data } = useQurey({
  queryKey: ['posts'],
  queryFn: getPosts,
  initialData: props.posts,
  })
  
  // ...
}