React Query는 비동기 데이터를 가져오고, 캐시하고, 동기화하며, 업데이트하고, 관리하는 작업을 수행, 이 라이브러리를 사용하면 컴포넌트가 서버 상태와 더 자연스럽게 상호 작용할 수 있으며, 캐싱, 동기화, 백그라운드 업데이트 등의 기능이 편리하게 제공(Component의 Lifecycle 구애 x)

서버의 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트 하는 작업을 도와주는 라이브러리

yarn add @tanstack/react-query

yarn add @tanstack/react-query-devtools

react-query 장점

여러가지 장점이 있지만 주로 아래와 같이 프론트 개발자가 구현하기 귀찮은 일들을 수행합니다.

  • 캐싱
  • get을 한 데이터에 대해 update를 하면 자동으로 get을 다시 수행한다. (예를 들면 게시판의 글을 가져왔을 때 게시판의 글을 생성하면 게시판 글을 get하는 api를 자동으로 실행 )
  • 데이터가 오래 되었다고 판단되면 다시 get (invalidateQueries)
  • 동일 데이터 여러번 요청하면 한번만 요청한다. (옵션에 따라 중복 호출 허용 시간 조절 가능)
  • 무한 스크롤 (Infinite Queries (opens new window))
  • 비동기 과정을 선언적으로 관리할 수 있다.
  • react hook과 사용하는 구조가 비슷하다

API 통신과 비동기 데이터 관리1를 위해 React Query를 적극적으로 활용(카카오페이)

🙌 「if(kakao)2021 - 카카오페이 프론트엔드 개발자들이 React Query를 선택한 이유」 세줄요약 🤟

  1. React Query는 React Application에서 서버 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트하는 작업을 도와주는 라이브러리입니다.
  2. 복잡하고 장황한 코드가 필요한 다른 데이터 불러오기 방식과 달리 React Component 내부에서 간단하고 직관적으로 API를 사용할 수 있습니다.
  3. 더 나아가 React Query에서 제공하는 캐싱, Window Focus Refetching 등 다양한 기능을 활용하여 API 요청과 관련된 번잡한 작업 없이 “핵심 로직”에 집중할 수 있습니다

<의견>

⇒ “보통 유저state를 유지해야하는 경우 store에 정보와 서버에 정보를 동시에 사용해야하는 경우가 생긴다, 그런경우 서버와 내가 저장한 유저state들이 공존하면서 공존하지 못하는 혼합데이터들이 생기거나 먼저 패치가 됬지만 다른 컴포넌트에서는 또 다른 값이 패치가 되는 등 문제가 생긴다. 이런 문제들을 방지하기 위한 서버와 클라이언트 데이터를 분리를 하도록한다.”

⇒ “번잡한 작업 없이 로직에 집중할 수 있는 큰 장점으로 매우 직관적이고 효율적인 코드 형식”

import axios from 'axios';
import {
  QueryClient,
  QueryClientProvider,
  useMutation,
  useQuery,
  useQueryClient,
} from 'react-query';

// React Query는 내부적으로 queryClient를 사용하여
// 각종 상태를 저장하고, 부가 기능을 제공합니다.
const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <Menus />
    </QueryClientProvider>
  );
}

function Menus() {
  const queryClient = useQueryClient();

  // "/menu" API에 Get 요청을 보내 서버의 데이터를 가져옵니다.
  const { data } = useQuery('getMenu', () =>
    axios.get('/menu').then(({ data }) => data),
  );

  // "/menu" API에 Post 요청을 보내 서버에 데이터를 저장합니다.
  const { mutate } = useMutation(
    (suggest) => axios.post('/menu', { suggest }),
    {
      // Post 요청이 성공하면 위 useQuery의 데이터를 초기화합니다.
      // 데이터가 초기화되면 useQuery는 서버의 데이터를 다시 불러옵니다.
      onSuccess: () => queryClient.invalidateQueries('getMenu'),
    },
  );

  return (
    <div>
      <h1> Tomorrow's Lunch Candidates! </h1>
      <ul>
        {data.map((item) => (
          <li key={item.id}> {item.title} </li>
        ))}
      </ul>

      <button
        onClick={() =>
          mutate({
            id: Date.now(),
            title: 'Toowoomba Pasta',
          })
        }
      >
        Suggest Tomorrow's Menu
      </button>
    </div>
  );
}

비동기적인 데이터를 처리하는 방식

1. 기본 쿼리 작성

jsxCopy code
import { useQuery } from 'react-query';

function Example() {
  const { data, error, isLoading } = useQuery('repoData', fetchRepoData);

  if (isLoading) {
    return 'Loading...';
  }

  if (error) {
    return 'An error has occurred: ' + error.message;
  }

  return (
    <div>
      {data.map(item => (
        <div key={item.id}>{item.name}</div>
      ))}
    </div>
  );
}

2. 뮤테이션 사용

jsxCopy code
import { useMutation } from 'react-query';

function UpdateUser() {
  const mutation = useMutation(updateUser, {
    onSuccess: () => {
      queryClient.invalidateQueries('userData');
    },
  });

  return (
    <button onClick={() => mutation.mutate({ id: 1, name: 'New Name' })}>
      Update User
    </button>
  );
}

3. 쿼리 리패치

jsxCopy code
const { data, refetch } = useQuery('repoData', fetchRepoData, {
  refetchOnWindowFocus: false,
});

return (
  <div>
    <button onClick={() => refetch()}>Refetch Data</button>
    {/* ... */}
  </div>
);

4. 쿼리 캐싱 및 데이터 가져오기

jsxCopy code
const { data } = useQuery('repoData', fetchRepoData, {
  staleTime: 1000 * 60 * 5, // 5 minutes
  cacheTime: 1000 * 60 * 60, // 1 hour
});

5. React Query Devtools 사용

jsxCopy code
import { ReactQueryDevtools } from 'react-query/devtools';

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* ... */}
      <ReactQueryDevtools initialIsOpen={false} />
    </QueryClientProvider>
  );
}

⇒ “리덕스에 비해 매우 적은 Boilerplate ⇒다양한 api사용법으로 콤포넌트 내부 더 중요한 비즈니스 로직에 집중에 집중할 수있음”

  • 하지만 의도치 않은 플래그로 리렌더링이 되거나 최적화를 잘 해야 하는 책임도 있음.

<참조>

https://tech.kakaopay.com/post/react-query-1/(리덕스의 사용 이유와 고민들이 잘나와있습니다.)

https://tanstack.com/query/latest/docs/react/overview?from=reactQueryV3&original=https%3A%2F%2Ftanstack.com%2Fquery%2Fv3%2Fdocs%2Foverview (리액트쿼리 공식사이트)

https://kyounghwan01.github.io/blog/React/react-query/basic/#react-query-장점(개인블로그)

0개의 댓글