본문으로 건너뛰기

비교 | React Query vs SWR vs Apollo vs RTK Query vs React Router

이 비교표는 최대한 정확하고 편향되지 않은 정보를 제공하고자 합니다. 이러한 라이브러리 중 하나를 사용하면서 정보를 개선할 수 있다고 생각한다면, 이 페이지 하단의 "Github에서 이 페이지 편집" 링크를 사용하여 자유롭게 변경 사항을 제안하세요(주장에 관한 메모나 근거 포함).

기능/역량 키:

  • ✅ 별도의 구성이나 코드 없이 바로 사용할 수 있는 일급 내장 기능
  • 🟡 지원되지만, 비공식 서드 파티 또는 커뮤니티 라이브러리/기여 형태입니다.
  • 🔶 지원되고 문서화되어 있지만 구현하려면 추가 사용자 코드가 필요합니다
  • 🛑 공식적으로 지원되거나 문서화되지 않았습니다.
React QuerySWR (웹사이트)Apollo Client (웹사이트)RTK-Query (웹사이트)React Router (웹사이트)
Github 저장소 / 스타 수
플랫폼 요구 사항ReactReactReact, GraphQLReduxReact
두 방식의 비교(없음)(없음)비교(없음)
지원되는 쿼리 구문Promise, REST, GraphQLPromise, REST, GraphQLGraphQL, 모든 타입(반응형 변수)Promise, REST, GraphQLPromise, REST, GraphQL
지원되는 프레임워크ReactReactReact + 기타모두React
캐싱 전략계층형 키 -> 값고유 키 -> 값정규화된 스키마고유 키 -> 값중첩 라우트 -> 값
캐시 키 전략JSONJSONGraphQL QueryJSON라우트 경로
캐시 변경 감지키 심층 비교(안정적 직렬화)키 심층 비교(안정적 직렬화)키 심층 비교(불안정한 직렬화)키 참조 동일성(===)라우트 변경
데이터 변경 감지심층 비교 + 구조적 공유심층 비교(stable-hash을 통해)심층 비교(불안정한 직렬화)키 참조 동일성(===)로더 실행
데이터 메모이제이션완전한 구조적 공유동일성 (===)정규화된 ID동일성 (===)동일성 (===)
번들 크기 +
API 정의 위치컴포넌트, 외부 구성컴포넌트GraphQL 스키마외부 구성라우트 트리 구성
쿼리
캐시 영구 저장🛑 활성 경로만 8
DevTools🛑
폴링/간격🛑
병렬 쿼리
종속 쿼리
페이지네이션된 쿼리
무한 쿼리🛑
양방향 무한 쿼리🔶🔶🛑
무한 쿼리 다시 가져오기🛑🛑
지연된 쿼리 데이터1
선택자🛑N/A
초기 데이터
스크롤 복원
캐시 조작🛑
오래된 쿼리 폐기
렌더링 일괄 처리 및 최적화2🛑
자동 가비지 컬렉션🛑🛑N/A
뮤테이션 훅
오프라인 뮤테이션 지원🛑🟡🛑🛑
API 프리페치
쿼리 취소🛑🛑🛑
부분 쿼리 일치3🔶N/A
재검증하는 동안 stale 상태 유지🛑
Stale Time 구성🛑7🛑🛑
사용 전 쿼리/뮤테이션 구성4🛑
창 포커스 시 다시 가져오기🛑🛑
네트워크 상태에 따른 다시 가져오기🛑
일반적인 캐시 디하이드레이션/리하이드레이션🛑
오프라인 캐싱🛑🔶🛑
React Suspense🛑
추상화된/프레임워크 독립적 코어🛑🛑
뮤테이션 후 자동 다시 가져오기5🔶🔶
정규화된 캐싱6🛑🛑🛑🛑

참고 사항

1 지연된 쿼리 데이터 - React Query는 다음 쿼리가 로드되는 동안 기존 쿼리의 데이터를 계속 볼 수 있는 방법을 제공합니다(Suspense가 곧 기본적으로 제공할 동일한 UX와 유사합니다). 이는 새 쿼리가 요청될 때마다 명확한 로딩 상태를 표시하고 싶지 않은 페이지네이션 UIs 또는 무한 로딩 UIs를 작성할 때 매우 중요합니다. 다른 라이브러리에는 이 기능이 없으며, 새 쿼리가 로드되는 동안 해당 쿼리에 대해 명확한 로딩 상태를 렌더링합니다(프리페치된 경우 제외).

2 렌더링 최적화 - React Query는 렌더링 성능이 매우 뛰어납니다. 기본적으로 접근한 필드를 자동으로 추적하며, 그중 하나가 변경될 때만 다시 렌더링합니다. 이 최적화를 사용하지 않으려면 notifyOnChangeProps'all'로 설정하여 쿼리가 업데이트될 때마다 컴포넌트를 다시 렌더링할 수 있습니다. 예를 들어 새 데이터가 생겼거나 가져오는 중임을 나타내기 위해 다시 렌더링합니다. 또한 React Query는 여러 컴포넌트가 동일한 쿼리를 사용할 때 애플리케이션이 한 번만 다시 렌더링되도록 업데이트를 일괄 처리합니다. data 또는 error 속성에만 관심이 있다면 notifyOnChangeProps['data', 'error']로 설정하여 렌더링 횟수를 더 줄일 수 있습니다.

3 부분 쿼리 일치 - React Query는 결정론적 쿼리 키 직렬화를 사용하므로, 일치시키려는 개별 query-key를 각각 알지 못해도 다양한 쿼리 그룹을 조작할 수 있습니다. 예를 들어 변수와 관계없이 키가 todos로 시작하는 모든 쿼리를 다시 가져오거나, 변수가 있거나 없는 특정 쿼리 또는 중첩 속성이 있는 특정 쿼리를 대상으로 지정할 수 있으며, 필터 함수를 사용하여 지정한 조건을 통과하는 쿼리만 일치시킬 수도 있습니다.

4 사용 전 쿼리 구성 - 이는 쿼리와 뮤테이션을 사용하기 전에 그 동작 방식을 구성할 수 있다는 것을 그럴듯하게 표현한 이름일 뿐입니다. 예를 들어 쿼리를 미리 기본값으로 완전히 구성할 수 있으며, 사용할 때가 되면 매번 가져오기 함수 및/또는 옵션을 전달할 필요 없이 useQuery({ queryKey })만 있으면 됩니다. SWR에도 기본 가져오기 함수를 미리 구성할 수 있게 하는 이 기능의 부분적인 형태가 있지만, 쿼리별이 아닌 전역 가져오기 함수로만 사용할 수 있고 뮤테이션에는 전혀 사용할 수 없습니다.

5 뮤테이션 후 자동 다시 가져오기 - 뮤테이션이 발생한 후 완전히 자동으로 다시 가져오기가 실행되려면 스키마(graphQL에서 제공하는 것과 같은 스키마)와 함께 라이브러리가 해당 스키마에서 개별 엔터티와 엔터티 유형을 식별하는 방법을 알 수 있게 하는 휴리스틱이 필요합니다.

6 정규화된 캐싱 - React Query, SWR 및 RTK-Query는 일부 상위 수준 데이터 중복을 방지하기 위해 엔터티를 평면 구조에 저장하는 자동 정규화 캐싱을 현재 지원하지 않습니다.

7 SWR의 불변 모드 - SWR에는 캐시가 유지되는 동안 쿼리를 한 번만 가져올 수 있게 하는 "불변" 모드가 포함되어 있지만, 여전히 stale-time이나 조건부 자동 재검증이라는 개념은 없습니다.

8 React Router 캐시 영구 저장 - React Router는 현재 일치하는 라우트 이외의 데이터를 캐시하지 않습니다. 라우트를 벗어나면 해당 데이터가 손실됩니다.