Powerful data fetching & caching tool for Redux
Crash Course!
Powerful data fetching & caching tool to simplify common cases & eliminate the need to hand-write the logic yourself"
No | Item | Description |
---|---|---|
1. | Total Commits | 1,043 |
2. | Last Commit | 3 hours ago |
3. | Opened Issues | 78 out of 831 |
4. | Opened Pull Requests | 17 out of 554 |
5. | Total Stars | 6.2k |
6. | Total Fork | 473 |
7. | First Public Release | 24 Dec 2018 (v0.3.0) |
8. | Latest version | v1.6.1 |
Creator of Redux
Redux rules:
Redux knows to synchronously dispatch actions, update the states and notify the UI that something changed. However, any asynchronous operations have to happen outside the store.
RTK Query is an optional addon included in Redux Toolkit (RTK) and its functionality is seamlessly integrated in the RTK API.
Solve common data fetching behaviors:
Item | React Query | SWR | Apollo Client | RTK-Query |
---|---|---|---|---|
Last Commits | 9 hours ago | 24 hours ago | 9 hours ago | ❤️8 hours ago |
No of Commits | 1,325 | 450 | ❤️ 9,932 | 1,049 |
No of Stars | ❤️ 22.5k | 18.9k | 16.7k | 6.2k |
First version | 11 Sept 2019 | 30 Oct 2019 | ❤️ 14 Apr 2016 | 7 June 2021 |
No of Issues ( Opened / Closed ) |
77 / 763 | 47 / 418 | ❤️ 345 / 3,507 | 77 / 763 |
No of PR ( Opened / Closed ) |
11 / 755 | 15 / 467 | ❤️96 / 4,449 | 17 / 541 |
Platform Requirements | React | React | React, GraphQL | Redux |
Supported Query Syntax | Promise, REST, GraphQL | Promise, REST, GraphQL | GraphQL | Promise, REST, GraphQL |
Supported Query Keys | JSON | JSON | GraphQL Query | JSON |
Change Detection | Deep Compare (Stable Serialization) | Shallow Compare | Deep Compare (Unstable Serialization) | Referential Equality (===) |
API Definition | On-Use, Declarative | On-Use | GraphQL Schema | Declarative |
React Query | SWR | Apollo Client | RTK-Query | |
---|---|---|---|---|
Caching | ✅ | ✅ | ✅ | ✅ |
Devtools | ✅ | 🟡 | ✅ | ✅ |
Polling/Intervals | ✅ | ✅ | ✅ | ✅ |
Parallel Queries | ✅ | ✅ | ✅ | ✅ |
Dependent Queries | ✅ | ✅ | ✅ | ✅ |
Paginated Queries | ✅ | ✅ | ✅ | ✅ |
Infinite Queries | ✅ | ✅ | ✅ | 🛑 |
Bi-directional Infinite Queries | ✅ | 🔶 | 🔶 | 🛑 |
Infinite Query Refetching | ✅ | ✅ | 🛑 | 🛑 |
Lagged Query Data | ✅ | 🔶 | 🛑 | ✅ |
Selectors | ✅ | 🛑 | ✅ | ✅ |
Initial Data | ✅ | ✅ | ✅ | ✅ |
Scroll Recovery | ✅ | ✅ | ✅ | ✅ |
React Query | SWR | Apollo Client | RTK-Query | |
---|---|---|---|---|
Cache Manipulation | ✅ | ✅ | ✅ | ✅ |
Outdated Query Dismissal | ✅ | ✅ | ✅ | ✅ |
Render Batching & Optimization | ✅ | 🛑 | 🛑 | ✅ |
Auto Garbage Collection | ✅ | 🛑 | 🛑 | ✅ |
Mutation Hooks | ✅ | 🟡 | ✅ | ✅ |
Offline Mutation Support | ✅ | 🛑 | 🟡 | 🛑 |
Prefetching APIs | ✅ | 🔶 | ✅ | ✅ |
Query Cancellation | ✅ | 🛑 | 🛑 | 🛑 |
Partial Query Matching3 | ✅ | 🛑 | 🛑 | ✅ |
Stale While Revalidate | ✅ | ✅ | ✅ | ✅ |
Stale Time Configuration7 | ✅ | 🛑 | 🛑 | ✅ |
React Query | SWR | Apollo Client | RTK-Query | |
---|---|---|---|---|
Pre-usage Query/Mutation Configuration | ✅ | 🛑 | 🛑 | ✅ |
Window Focus Refetching | ✅ | ✅ | 🛑 | ✅ |
Network Status Refetching | ✅ | ✅ | ✅ | ✅ |
General Cache Dehydration/Rehydration | ✅ | 🛑 | ✅ | ✅ |
Offline Caching | ✅ (Experimental) | 🛑 | ✅ | 🔶 |
React Suspense (Experimental) | ✅ | ✅ | 🛑 | 🛑 |
Abstracted/Agnostic Core | ✅ | 🛑 | ✅ | ✅ |
Automatic Refetch after Mutation | 🔶 | 🔶 | ✅ | ✅ |
Normalized Caching | 🛑 | 🛑 | ✅ | 🛑 |
> npm install @reduxjs/toolkit redux react-redux
1. Add the Redux Toolkit and React-Redux packages to your project:
// app/store.js
import postsReducer from '../features/posts/postsSlice'
import usersReducer from '../features/users/usersSlice'
import notificationsReducer from '../features/notifications/notificationsSlice'
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {
posts: postsReducer,
users: usersReducer,
notifications: notificationsReducer,
}
})
2. Create an Redux Store
3. Provide the Redux Store to React
4. Create a redux state api
5. Add API slice to Store
import { useGetPostsQuery } from '../api/apiSlice'
export const PostsList = () => {
const {
data: posts,
isLoading,
isSuccess,
isError,
error
} = useGetPostsQuery()
let content
if (isLoading) {
content = <Spinner text="Loading..." />
} else if (isSuccess) {
content = posts.map(post => <PostExcerpt key={post.id} post={post} />)
} else if (isError) {
content = <div>{error.toString()}</div>
}
return (
<section className="posts-list">
<h2>Posts</h2>
{content}
</section>
)
}
let PostExcerpt = ({ post }) => {
return (
<article className="post-excerpt" key={post.id}>
<h3>{post.title}</h3>
<div>
<PostAuthor userId={post.user} />
<TimeAgo timestamp={post.date} />
</div>
<p className="post-content">{post.content.substring(0, 100)}</p>
<ReactionButtons post={post} />
<Link to={`/posts/${post.id}`} className="button muted-button">
View Post
</Link>
</article>
)
}
Websites
Comparison Page