Skip to content

Commit 9f7e0ad

Browse files
committed
Remove serialization FAQ and add detailed caching example
- Removed the FAQ about serialization support (unnecessary discussion) - Expanded the caching section with a detailed example showing how query keys with route params trigger automatic cache invalidation - Added clear navigation flow example demonstrating cache hits/misses
1 parent e55e690 commit 9f7e0ad

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

src/blog/composite-components.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,45 @@ function PostPage() {
185185

186186
### With Query caching
187187

188+
Because server components are just data, they integrate naturally with TanStack Query's caching model. The query key determines cache identity—include route params and the cache automatically invalidates when they change:
189+
190+
```tsx
191+
function PostPage() {
192+
const { postId } = Route.useParams()
193+
194+
const { data: Post } = useQuery({
195+
queryKey: ['post', postId],
196+
queryFn: () => getPost({ data: { postId } }),
197+
staleTime: 5 * 60 * 1000,
198+
})
199+
200+
if (!Post) return <PostSkeleton />
201+
202+
return (
203+
<Post renderActions={({ postId }) => <PostActions postId={postId} />}>
204+
<Comments postId={postId} />
205+
</Post>
206+
)
207+
}
208+
```
209+
210+
**What happens when the user navigates:**
211+
212+
- `/posts/abc` → fetches and caches the server component for post `abc`
213+
- `/posts/xyz` → cache miss on `['post', 'xyz']`, fetches post `xyz`
214+
- `/posts/abc` → cache hit, instant render from cache (within staleTime)
215+
216+
The server component for post `abc` is still in the cache. Navigate back and it renders immediately—no network request, no loading state. The entire rendered UI tree is preserved.
217+
218+
This works because **the RSC payload is the cache value**. Query doesn't know or care that it's caching a server component. It's just bytes that happen to decode into a React element tree.
219+
220+
For static content that rarely changes, you can cache aggressively:
221+
188222
```tsx
189223
const { data: Layout } = useQuery({
190224
queryKey: ['layout'],
191225
queryFn: () => getLayout(),
192-
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
226+
staleTime: Infinity, // Cache forever, refetch manually
193227
})
194228
```
195229

@@ -303,10 +337,6 @@ No. RSCs are entirely opt-in. You can build fully client-side SPAs with TanStack
303337

304338
TanStack Start's RSC implementation builds on React's Flight protocol and works with React 19. Server Actions are a separate primitive. `createServerFn` serves a similar purpose but integrates with TanStack's middleware, validation, and caching model. We're watching the Server Actions API and will align where it makes sense.
305339

306-
### When will TanStack Start's full serialization work inside RSCs?
307-
308-
It's on the roadmap. The current release uses React's Flight serializer directly, which handles the core use cases. Unifying with TanStack Start's serializer for custom types, extended serialization, and tighter TanStack DB integration is planned for a future release.
309-
310340
### Can I define my component outside of `createServerComponent`?
311341

312342
Yes. `createServerComponent` initiates the RSC stream generation, but your component can be defined separately and invoked inside:

0 commit comments

Comments
 (0)