Gwangju-Web-Study / WoowahanTS_Study

✏️우아한 타입스크립트 with 리액트 스터디
6 stars 2 forks source link

7.4 React-Query에 대해 설명해주세요 #32

Open hyeonseong2023 opened 3 days ago

hyeonseong2023 commented 3 days ago

📝 p247

❓ React-Query에 대해 설명해주세요 책의 중간 중간 React-Query가 등장하는데, (1)React-Query의 사용 이유와 (2)앞 사람과의 중복 없이 장점 하나를 예시 코드와 함께 설명해주세요!

fe-Jay commented 2 days ago

개요

  1. 공식문서 : https://tanstack.com/query/latest
  2. 등장 배경
    • 복잡한 비동기 상태 관리의 필요성
    • 서버 ↔ 클라이언트 상태의 효율적인 관리의 필요성
    • REST API, GraphQL 등 다양한 데이터 소스에 대한 통합된 접근 방식의 필요성
  3. 주요 기능
    • 캐싱 및 자동 리프레시
    • 백그라운드 데이터 업데이트
    • 페이지네이션 및 무한 스크롤 지원
    • 낙관적 업데이트 (UI 업데이트)
    • 서버 상태 관리 및 에러핸들링
  4. 사용법
    • QueryClient 생성 및 Provider 설정
    • useQuery 훅을 사용하여 데이터 페칭
    • useMutation 훅으로 데이터 변경 처리

예제코드

gwangminjun commented 1 day ago

React-Query

정의

React-Query는 React 애플리케이션에서 데이터 가져오기, 캐싱, 동기화 등 다양한 데이터 관리 문제를 해결하기 위한 강력한 라이브러리

사용이유

  1. 데이터 가져오기 추상화:

    • React-Query는 데이터 가져오기 로직캡슐화하여 재사용성과 유지 보수성을 높입니다.
    • 이를 통해 개발자들은 데이터 가져오기 코드를 반복하지 않고 집중할 수 있습니다.
  2. 자동 캐싱 및 상태 관리:

  1. 최적화된 렌더링:
  1. 엣지 케이스 처리:
  1. 타이밍 및 재시도 관리:

사용법

  1. QueryClient 생성:
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

const queryClient = new QueryClient();
  1. QueryClientProvider 사용:
function App() {
  return (
    <QueryClientProvider client={queryClient}>
      {/* 애플리케이션 내용 */}
    </QueryClientProvider>
  );
}
  1. useQuery 사용:
function UserList() {
  //useInfiniteQuery = 페이지 정보를 관리할 수 있는 훅
  //React-Query의 주요 훅 중 하나로,
  //무한 스크롤이나 페이지네이션과 같은 데이터 페칭 기능을 쉽게 구현
  const { data, error, isLoading, isFetching, fetchNextPage, hasNextPage } =
    //users = 데이터를 식별하는 쿼리키
    useInfiniteQuery("users", fetchUsers, {
      //getNextPageParam  = 다음 페이지의 커서 정보를 반환하는 함수
      getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
    });

  //isLoading 상태가 true이면 "Loading..."을 렌더링
  if (isLoading) return <div>Loading...</div>;
  //error 객체가 있으면 에러 메시지를 렌더링
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <ul>
        //모든 페이지의 결과를 평면화하여 하나의 평면 배열로 변경 // map()을
        사용하여 렌더링
        {data?.pages.flatMap((page) =>
          page.results.map((user) => (
            <li key={user.id}>
              {user.name} - {user.email}
            </li>
          ))
        )}
      </ul>
      //hasNextPage가 true이면 사용자에게 "Load More" 버튼 표출
      {hasNextPage && (
        <button onClick={() => fetchNextPage()} disabled={isFetching}>
          //true이면 사용자에게 "Loading..." 메시지 표출
          {isFetching ? "Loading more..." : "Load More"}
        </button>
      )}
    </div>
  );
}

//현재 페이지 정보(커서)를 받아 다음 페이지의 데이터를 가져오는 함수.
//최초 호출 시에는 pageParam이 0
//이후 호출 시에는 이전 페이지의 nextCursor 값이 pageParam으로 전달.
async function fetchUsers({ pageParam = 0 }) {
  const response = await fetch(`/api/users?cursor=${pageParam}`);
  const data = await response.json();
  return { results: data.users, nextCursor: data.nextCursor };
}