Comparison | React Query vs SWR vs Apollo vs RTK Query vs React Router
"이 표는 정확하고 공정하게 작성되었습니다. 이 라이브러리 중
어떤 것을 사용하고 있으며 정보 개선이 필요하다고 느끼신다면, 페이지 하단의
"Edit this page on Github" 링크를 사용하여 변경 제안(주장에 대한 주석이나
근거 포함)을 자유롭게 제출해 주세요."
단위:
✅ 일급 객체, 내장되어 있으며 추가 설정이나 코드 없이 바로 사용 가능
🟡 지원되지만 비공식적인 third-party나 커뮤니티 라이브러리/기여
🔶 지원되며 문서화되어 있지만, 구현에 추가 사용자 코드가 필요
🛑 공식적으로 지원되지 않거나 문서화되지 않음
React Query | SWR | Apollo Client | RTK-Query | React Router | |
---|---|---|---|---|---|
Platform Requirements | React | React | React, GraphQL | Redux | React |
Supported Query Syntax | Promise, REST, GraphQL | Promise, REST, GraphQL | GraphQL, Any (Reactive Variables) | Promise, REST, GraphQL | Promise, REST, GraphQL |
Supported Frameworks | React | React | React + Others | Any | React |
Caching Strategy | Hierarchical Key -> Value | Unique Key -> Value | Normalized Schema | Unique Key -> Value | Nested Route -> value |
Cache Key Strategy | JSON | JSON | GraphQL Query | JSON | Route Path |
Cache Change Detection | Deep Compare Keys (Stable Serialization) | Deep Compare Keys (Stable Serialization) | Deep Compare Keys (Unstable Serialization) | Key Referential Equality (===) | Route Change |
Data Change Detection | Deep Comparison + Structural Sharing | Deep Compare (via stable-hash ) | Deep Compare (Unstable Serialization) | Key Referential Equality (===) | Loader Run |
Data Memoization | Full Structural Sharing | Identity (===) | Normalized Identity | Identity (===) | Identity (===) |
API Definition Location | Component, External Config | Component | GraphQL Schema | External Config | Route Tree Configuration |
Queries | ✅ | ✅ | ✅ | ✅ | ✅ |
Cache Persistence | ✅ | ✅ | ✅ | ✅ | 🛑 Active Routes Only 8 |
Devtools | ✅ | ✅ | ✅ | ✅ | 🛑 |
Polling/Intervals | ✅ | ✅ | ✅ | ✅ | 🛑 |
Parallel Queries | ✅ | ✅ | ✅ | ✅ | ✅ |
Dependent Queries | ✅ | ✅ | ✅ | ✅ | ✅ |
Paginated Queries | ✅ | ✅ | ✅ | ✅ | ✅ |
Infinite Queries | ✅ | ✅ | ✅ | 🛑 | 🛑 |
Bi-directional Infinite Queries | ✅ | 🔶 | 🔶 | 🛑 | 🛑 |
Infinite Query Refetching | ✅ | ✅ | 🛑 | 🛑 | 🛑 |
Lagged Query Data1 | ✅ | ✅ | ✅ | ✅ | ✅ |
Selectors | ✅ | 🛑 | ✅ | ✅ | N/A |
Initial Data | ✅ | ✅ | ✅ | ✅ | ✅ |
Scroll Recovery | ✅ | ✅ | ✅ | ✅ | ✅ |
Cache Manipulation | ✅ | ✅ | ✅ | ✅ | 🛑 |
Outdated Query Dismissal | ✅ | ✅ | ✅ | ✅ | ✅ |
Render Batching & Optimization2 | ✅ | ✅ | 🛑 | ✅ | ✅ |
Auto Garbage Collection | ✅ | 🛑 | 🛑 | ✅ | N/A |
Mutation Hooks | ✅ | ✅ | ✅ | ✅ | ✅ |
Offline Mutation Support | ✅ | 🛑 | 🟡 | 🛑 | 🛑 |
Prefetching APIs | ✅ | ✅ | ✅ | ✅ | ✅ |
Query Cancellation | ✅ | 🛑 | 🛑 | 🛑 | ✅ |
Partial Query Matching3 | ✅ | 🔶 | ✅ | ✅ | N/A |
Stale While Revalidate | ✅ | ✅ | ✅ | ✅ | 🛑 |
Stale Time Configuration | ✅ | 🛑7 | 🛑 | ✅ | 🛑 |
Pre-usage Query/Mutation Configuration4 | ✅ | 🛑 | ✅ | ✅ | ✅ |
Window Focus Refetching | ✅ | ✅ | 🛑 | ✅ | 🛑 |
Network Status Refetching | ✅ | ✅ | ✅ | ✅ | 🛑 |
General Cache Dehydration/Rehydration | ✅ | 🛑 | ✅ | ✅ | ✅ |
Offline Caching | ✅ | 🛑 | ✅ | 🔶 | 🛑 |
React Suspense | ✅ | ✅ | ✅ | 🛑 | ✅ |
Abstracted/Agnostic Core | ✅ | 🛑 | ✅ | ✅ | 🛑 |
Automatic Refetch after Mutation5 | 🔶 | 🔶 | ✅ | ✅ | ✅ |
Normalized Caching6 | 🛑 | 🛑 | ✅ | 🛑 | 🛑 |
1 Lagged Query Data - React Query는 다음 query가 로드되는 동안 기존 query의 데이터를 계속 볼 수 있는 방법을 제공합니다(곧 suspense가 기본적으로 제공할 것과 유사한 UX). 이는 pagination UI 또는 무한 로딩 UI를 작성할 때 매우 중요합니다. 새로운 query가 요청될 때마다 하드 로딩 상태를 표시하지 않기를 원하기 때문입니다. 다른 라이브러리에는 이 기능이 없으며(사전 로드된 경우 제외) 새로운 query가 로드되는 동안 하드 로딩 상태를 렌더링합니다.
2 Render Optimization - React Query는 뛰어난 렌더링 성능을 제공합니다. 기본적으로, 접근된 필드를 자동으로 추적하고 그 중 하나가 변경될 때만 다시 렌더링됩니다. 이 최적화를 사용하지 않으려면
notifyOnChangeProps
를'all'
로 설정하여 query가 업데이트될 때마다 컴포넌트를 다시 렌더링할 수 있습니다. 예를 들면 새로운 데이터가 있을 때 또는 가져오고 있음을 나타내기 위해서 사용합니다. React Query는 동일한 query를 사용하는 여러 컴포넌트가 있을 때 한 번만 다시 렌더링하도록 업데이트를 함께 batch합니다.data
또는error
속성만 필요한 경우notifyOnChangeProps
를['data', 'error']
로 설정하여 렌더링 횟수를 더욱 줄일 수 있습니다.
3 Partial query matching - React Query는 쿼리 키를 직렬화하기 때문에, 각각의 queryKey를 알 필요 없이 다양한 query 그룹을 조작할 수 있습니다. 예를 들어, 변수에 관계없이
todos
queryKey로 시작하는 모든 query를 refetch할 수 있으며, 특정 변수나 중첩된 속성이 있는(또는 없는) 특정 query를 타겟팅하거나, 특정 조건을 충족하는 query만 일치시키기 위해 필터 함수를 사용할 수도 있습니다.
4 Pre-usage Query Configuration - 이는 query와 mutation이 사용되기 전에 작동 방식을 구성할 수 있다는 뜻입니다. 예를 들어, query는 디폴트값으로 사전에 구성될 수 있으며 사용 시
useQuery({ queryKey })
만 필요하며, 매번 fetch 함수 또는 옵션을 전달할 필요가 없습니다. SWR에는 이 기능의 일부 형태가 있으며 기본 fetch 함수를 사전 구성할 수 있지만 전역 fetch 함수만 가능하며, 개별 쿼리 기반이 아니며 mutation에도 적용되지 않습니다.
5 Automatic Refetch after Mutation - mutation이 발생한 후 진정한 자동 refetch가 이루어지려면, 스키마가 필요하며(예: GraphQL이 제공하는 것) 라이브러리가 해당 스키마에서 개별 엔터티 및 엔터티 유형을 식별하는 방법을 알아야 합니다.
6 Normalized Caching - React Query, SWR 및 RTK-Query는 현재 상위 수준 데이터 중복을 피하기 위해 엔터티를 평면 구조로 저장하는 자동 정규화된 캐싱을 지원하지 않습니다.
7 SWR's Immutable Mode - SWR은 "Immutable" 모드가 포함되어 있으며 캐시 수명 동안 query를 한 번만 가져오도록 허용하지만, 여전히 유효 시간 또는 조건부 자동 재검증 개념은 없습니다.
8 React Router cache persistence - React Router는 현재 일치하는 경로 외의 데이터를 캐시하지 않습니다. 경로를 벗어나면 데이터가 손실됩니다.
Changed History
2024.08.26. @ubinquitous
- [용어] 기능/능력 키 → 단위