This project is a work in progress. If you have any feedback, please let me know.
| Technique | Data Fetching | Pros | Cons |
|---|---|---|---|
Client based | Data fetching starts on the client side after component mount Triggered by useEffect hook, runs after initial render, client calls the API, which calls the database |
|
|
RSC based | Data fetching is fully done in a parent wrapper RSC Triggered after the http request, blocks the rendering of the RSCs until their data is fetched |
|
|
use hook based | Data fetching starts in any parent RSC and is passed to the client Triggered after the http request, blocks the rendering of the client components consuming the promise |
|
|
In Next.js, navigation can always be instant using prefetching. However, we might not always want to prefetch and this navigation might show a loading.js, which is much less exciting than having the actual page with fresh data available. Below we explore how to instantly get the page we want, with stale or fresh data.
| State Manager | Data Fetching | Pros | Cons | Data Availability |
|---|---|---|---|---|
Vanilla React | Client |
|
| First Load: Data fetched on mount |
Subsequent: via context + router cache | ||||
Vanilla React | Awaited in RSC |
|
| First Load: With Next.js prefetching only |
Subsequent: With Next.js prefetching only | ||||
Vanilla React | Passed from RSC |
| First Load: With Next.js prefetching | |
Subsequent: Through router cache | ||||
Jotai | Client |
|
| First Load: Data fetched on mount |
Subsequent: Via atom + router cache | ||||
Jotai | Awaited in RSC |
|
| First Load: With Next.js prefetching only |
Subsequent: With Next.js prefetching only | ||||
Jotai | Passed from RSC |
|
| First Load: Actions don't work |
Subsequent: Actions don't work | ||||
Zustand | Client |
|
| First Load: Data fetched on mount |
Subsequent: Via store + router cache | ||||
Zustand | Awaited in RSC |
| First Load: With Next.js prefetching | |
Subsequent: With Next.js prefetching | ||||
Zustand | Passed from RSC |
| First Load: Doesn't seem to work | |
Subsequent: Doesn't seem to work | ||||
React Query | Client |
|
| First Load: Data fetched on mount |
Subsequent: via queryCache + router cache | ||||
React Query | Awaited in RSC |
|
| First Load: With Next.js prefetching |
Subsequent: With Next.js prefetching | ||||
React Query | Passed from RSC |
|
| First Load: With Next.js prefetching |
Subsequent: via queryCache + router cache | ||||
SWR | Client |
|
| First Load: Data fetched on mount |
Subsequent: via SWR cache + router cache | ||||
SWR | Awaited in RSC |
|
| First Load: With Next.js prefetching only |
Subsequent: With Next.js prefetching only | ||||
SWR | Passed from RSC |
|
| First Load: With Next.js prefetching only |
Subsequent: Once put in the cache, it's instant |