Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react-query): next-app-router example with prefetch helpers #5451

Open
wants to merge 18 commits into
base: next
Choose a base branch
from

Conversation

juliusmarminge
Copy link
Member

@juliusmarminge juliusmarminge commented Feb 6, 2024

More integrated version of t3-oss/create-t3-turbo#877

adds a wrapped proxy around createCaller that sets data to a server-side QueryClient. devs can then choose to wrap some client component that needs some server prefetched data with the <HydrateClient> component. no network requests will be made from client components until the prefetched data goes stale:

https://utfs.io/f/8278fdc7-572e-4b14-9f10-5f9fece747bb-yl67w4.15.58.mp4

Also got a <PrefetchQuery query={}> HOC if you just wanna prefetch data in RSC without using said data in it. This makes for easier composition since you wouldn't need to create new components just to await the query in it, if you don't wanna block all the way up (if that makes sense)

This gives the same behavior as the ReactQueryStreamedProvider, but you can do authed procedures since there's no fetching in client componetns, even on the server, so no need to hack the RSC headers into the CC which causes some weird security concerns

CleanShot.2024-03-07.at.23.03.56.mp4

Copy link

vercel bot commented Feb 6, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-prisma-starter ✅ Ready (Inspect) Visit Preview Mar 7, 2024 10:07pm
og-image ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 7, 2024 10:07pm
trpc-next-app-dir ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 7, 2024 10:07pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 7, 2024 10:07pm

Copy link

github-actions bot commented Feb 6, 2024

Diagnostics Comparison

Numbers

Metric PR next
Files 780 779 (🔺 1)
Lines of Library 40,640 40,640 (➖ 0)
Lines of Definitions 117,390 117,235 (🔺 155)
Lines of TypeScript 4,967 4,967 (➖ 0)
Lines of JavaScript 0 0 (➖ 0)
Lines of JSON 0 0 (➖ 0)
Lines of Other 0 0 (➖ 0)
Identifiers 173,961 173,922 (🔺 39)
Symbols 108,098 108,071 (🔺 27)
Types 89 89 (➖ 0)
Instantiations 0 0 (➖ 0)
Memory used 172,427 175,006 (🔽🟢 -2,579)
Assignability cache size 0 0 (➖ 0)
Identity cache size 0 0 (➖ 0)
Subtype cache size 0 0 (➖ 0)
Strict subtype cache size 0 0 (➖ 0)

Timings and averages

Metric PR next
max (s) 4.414 4.454 (🔽🟢 -0.04)
min (s) 4.414 4.454 (🔽🟢 -0.04)
avg (s) 4.414 4.454 (🔽🟢 -0.04)
median (s) 4.414 4.454 (🔽🟢 -0.04)
length 1 1 (➖ 0)
unstable timings

Unstable

Timings are not reliable in here

Metric PR next
I/O Read time 0.04 0.05 (🔽🟢 -0.01)
Parse time 0.72 0.72 (➖ 0)
ResolveTypeReference time 0.03 0.03 (➖ 0)
ResolveModule time 0.11 0.11 (➖ 0)
ResolveLibrary time 0.02 0.02 (➖ 0)
Program time 1.05 1.06 (🔽🟢 -0.01)
Bind time 0.43 0.47 (🔽🟢 -0.04)
Total time 1.48 1.53 (🔽🟢 -0.05)

KATT
KATT previously approved these changes Mar 2, 2024
<UserButton />
</div>
</Suspense>
<HydrateClient>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good that this is contextual

if you have many of these, i guess they keep on sending stuff doubly? it would stack up quite a lot of it was used a lot

maybe we could keep track of stuff that's already been sent to the client so we don't send same query times across many hydration boundaries

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you have many of these, i guess they keep on sending stuff doubly? it would stack up quite a lot of it was used a lot

i would actually have thought RQ would handle this internally. isn't this an issue no matter where you use them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @TkDodo - do you handle deduping?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no deduplication with HydrationBoundary. Every boundary will send its content to the client.

@Ephem we talked about this some time ago I think ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is if you use the same queryClient maybe ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we've moved away from this recommendation precisely because of this:

https://tanstack.com/query/v5/docs/framework/react/guides/advanced-ssr#alternative-use-a-single-queryclient-for-prefetching

In the example above, we create a new queryClient for each Server Component that fetches data. This is the recommended approach, but if you want to, you can alternatively create a single one that is reused across all Server Components:

also:

As a future improvement, we might look into creating a dehydrateNew() function (name pending) that only dehydrate queries that are new since the last call to dehydrateNew(). Feel free to get in touch if this sounds interesting and like something you want to help out with!

Is this you getting in touch to implement that feature 😅 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha ;)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah, I forgot I used ye old "document the flaw and hope someone fixes it" approach here.. 😂

To be clear, it never dedupes, no matter if it's one queryClient or not. Compression does remove some of the overhead, but I think less than usual when streaming. Implementing dehydrateNew seems relatively straightforward on the surface, but I'm not sure if there are any hidden footguns or edge cases. 🤷

@dBianchii
Copy link
Contributor

This is great. Having to manually pass around initialData to client components, or doing manual prefetching and dehydration does feel very repetitive. Hope this can be merged soon.

@masterjanic
Copy link

Would love to have this feature as well, it would save me so much time ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants