Next.js - react-query 적용하기

박상준·2024년 6월 24일

react-query

Taskuit프로젝트는 잠시 접어두고 다시 Linkbrary를 들고왔다. 너무 방치되어 있었다. 드디어 듣기만 하던 리액트 쿼리를 적용해보겠다. 그동안 비동기로 api처리를 하면서 복잡하고 어려웠는데 이제 조금 나아지지 않을까 싶다.

react-query란?

리액트 쿼리는 비동기로 서버에서 받아오는 데이터를 효율적으로 관리하고 처리하기 위해 등장했다. 전까지 api를 다루는 방법을 간단하게 돌아보겠다.

function useGetFolderList(userId: string, folderId?: string) {
  const [link, setLink] = useState<Folders>([]);
  const [linkLoading, setLinkLoading] = useState(false);

  useEffect(() => {
    if (!userId) {
      return;
    }
    try {
      setLinkLoading(true);
      const loadFolderList = async () => {
        const links = await getFolder(userId);
        setLink(links.data);
        setLinkLoading(false);
      };
      loadFolderList();
    } catch (error) {
      console.error();
    }
  }, [userId, folderId]);
  ...

데이터를 불러오는 상태와 에러등을 고려해 비동기상태를 활용하기 위한 커스텀 훅이다. 엄청 복잡한 것은 아니지만 결국 코드양만 늘어난 것이다. 그리고 페이지가 전환되거나 컴포넌트가 리렌더링되는 시기마다 매번 api요청을 보내게된다. 하지만 react-query는 이 모든 문제점을 부숴버린다.

리액트 쿼리를 사용하면 기본적으로 pending,error등의 상태를 포함해서 데이터를 보내준다. 그럼 매번 커스텀훅을 만들어서 비동기 상태를 처리할 필요가 없어진다. 그리고 가장 큰 장점은 데이터를 매번 새로 불러오는 것이 아니라 데이터를 최신화하는 시기도 지정이 가능하고 기존의 데이터는 캐싱이라는 기능을 활용해 효율적으로 데이터 사용이 가능하다. 자세한 내용은 뒤에 다시 정리해보겠다.

복잡하기만했던 리액트 비동기 처리를 조금더 간단하게 만들어준다. 앞으로 코딩하는게 더 재밌어지지 않을까 싶다.

react-query 설치 및 세팅

npm install @tanstack/react-query

우선 프로젝트에 리액트 쿼리를 설치해준다. 그리고 추가적으로

npm install @tanstack/react-query-devtools

개발 툴을 설치해준다. 개발 툴은 리액트 쿼리를 사용하면서 데이터 상태를 확인하는 기능이다. 이제 기본설정을 해보자.

const queryClient = new QueryClient();

...

<QueryClientProvider client={queryClient}>
		...
      <Component {...pageProps} />
		...
  <ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>

먼저 쿼리를 사용하기 위해 app.tsx파일에서 QueryClient를 만들어준다. 그리고 context값을 만드는 것처럼 provider를 설정해줘서 프로젝트 전반에 거쳐 쿼리를 사용할 수 있도록 만들어주는 것이다. 그래서 QueryClientProvider로 프로젝트 컴포넌트를 감싸준다. 이제 프로젝트에서 쿼리를 사용할 수 있다.

그리고 추가로 설치한 쿼리 개발 툴을 추가해준다. open옵션은 일단 false로 두겠다. 이제 프로젝트를 실행해보면

오른쪽 구석에 해당 아이콘이 생긴다. 눌러보면

이렇게 쿼리 데이터 확인이 가능하다.

useQuery

본격적으로 쿼리를 사용해보도록 하겠다. useQuery는 api에서 대부분의 get요청을 할때 사용한다. 실제로 적용해보면서 정리해보겠다.

  const { data: user } = useQuery({
    queryKey: ['user'],
    queryFn: () => getUser(),
  });

우선 queryKey를 등록해줘야한다. 그러면 쿼리 데이터를 해당 key값으로 저장한다.

해당 key값으로 저장된 데이터를 확인할 수 있다. 이 key값에 저장된 값을 확인해 직접 사용하고 데이터 상태도 확인할 수 있다.

다음으로 queryFn을 등록해준다. 여기에는 비동기로 동작해 데이터를 받아오는 함수를 넣어준다. 이제 자동으로 데이터를 받아온다. 이렇게 받아온 데이터를 확인해보겠다.

이렇게 다양한 정보를 담은 객체를 보내준다. 데이터의 상태도 포함하고 있고 데이터를 받아오는 시간도 확인이 가능하다. 이렇게 다양한 값들을 가져와 여러 상황에 적용하는 것이다.

query status, fetch status

리액트 쿼리에서 두가지 상태에 대해서 알아보겠다.

query status

리액트 쿼리가 데이터를 받아온 상태를 나타내는 것이다.

pending, success, error

총 3가지 상태를 가지고 있다. 데이터를 받아오지 못했을때는 pending상태이다. 그리고 받아오면 success, 중간에 에러가 발생했다면 error상태를 가진다.

리액트 쿼리의 결과를 콘솔로 확인해보면 status에서 query status를 확인할 수 있다. 처음 데이터를 불러왔을때에는 pending상태이다. 그리고 데이터를 받아오면

success로 상태가 바뀐다.

fetch status

리액트 쿼리에 queryFn으로 등록한 api상태를 나타낸다.

fetching, paused, idle

fetch status도 3가지 상태로 나뉜다. 처음 함수가 실행되면 fetching상태이다. 만약 실행했는데 네트워크 문제등으로 제대로 동작하지 않는다면 paused상태로 바뀐다. 그리고 함수가 제대로 종료됬다면 idle상태이다.

fetch status도 확인이 가능하다. 처음 데이터를 불러오는 시점에서 함수가 실행되고 fetching상태인 것을 볼수 있다.

이후에 함수가 종료되고 데이터를 받아오면 idle상태인 것을 확인이 가능하다.

상태값 활용

이런 상태값이 왜 필요할까? 전에 커스텀훅을 이용해 데이터를 받아오는 시점에 로딩 컴포넌트가 렌더링되도록 만들었었다. 하지만 이제 리액트쿼리의 상태 값을 사용하면 된다. 그리고 다양한 상태값을 이용해 여러 상황에 맞게 대처가 가능하다.

예를 들어 pending/fetching 상태에서 정상적으로 종료되면 success/idle상태가 되고 에러가 발생하면 error/idle상태가 된다. 이렇게 여러 상황에 맞게 컨트롤이 가능해진다.

마무리

우선 포스팅이 길어지는 관계로 다음 포스트에서 리액트 쿼리의 핵심인 캐싱에 대해서 정리해보겠다.

profile
개인 블로그 플렛폼도 운영중입니다(https://blog-park.vercel.app/)

0개의 댓글