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

SSR docs rewrite #5966

Merged
merged 11 commits into from
Sep 26, 2023
Merged

SSR docs rewrite #5966

merged 11 commits into from
Sep 26, 2023

Conversation

Ephem
Copy link
Collaborator

@Ephem Ephem commented Sep 6, 2023

Most of this content is applicable in v4 as well, except for naming of useSuspenseQuery etc, but I've written and targeted this to the v5 branch.

There are four guides that progressively builds knowledge:

  • Performance & Request Waterfalls (new)
    • This is just about Request Waterfalls performance today, and that's reflected by the slug. We could add other performance tips later or split that to it's own page. This is mostly a background/foundation page, but does include practical tips too.
  • Prefetching & Router Integration
    • Client focused, but lays the foundation for the server parts.
    • Mostly kept the old content around at the top of the page for quick reference.
  • Server Rendering & Hydration
  • Advanced Server Rendering (new)

I'm open to suggestions on naming for the pages.

There are two existing doc pages that are related to these:

I'm not sure what to do with these. While there is some duplicate content there, they are also short and practical so I think I'm leaning towards keeping them around for discoverability. It's also good that these are mentioned early/high up in the guide pages navigation, while these 4 guides are more in depth and makes sense to have further down in the navigation.

I removed some content related to setting up React Query with custom SSR solutions. I don't think that's relevant to a majority of people, and the step by step instructions are still there so people can figure it out. If we want this I think it would fit better as an example, but I wont include that in this PR. Other than that, I don't think I removed any information, just added, rewrote or restructured.

@vercel
Copy link

vercel bot commented Sep 6, 2023

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

1 Ignored Deployment
Name Status Preview Comments Updated (UTC)
query ⬜️ Ignored (Inspect) Visit Preview Sep 25, 2023 5:54pm

@nx-cloud
Copy link

nx-cloud bot commented Sep 6, 2023

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 0c846b9. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this branch


⌛ The following target is in progress


Sent with 💌 from NxCloud.

@codesandbox-ci
Copy link

codesandbox-ci bot commented Sep 6, 2023

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 0c846b9:

Sandbox Source
@tanstack/query-example-react-basic-typescript Configuration
@tanstack/query-example-solid-basic-typescript Configuration
@tanstack/query-example-svelte-basic Configuration
@tanstack/query-example-vue-basic Configuration

Copy link
Collaborator

@TkDodo TkDodo left a comment

Choose a reason for hiding this comment

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

awesome work so far @Ephem 👏


Before jumping into the different specific prefetch patterns, let's look at the `prefetchQuery` and `prefetchInfiniteQuery` functions. First a few basics:

- If **fresh** data for this query is already in the cache, the data will not be fetched
Copy link
Collaborator

Choose a reason for hiding this comment

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

That's technically true, but can be quite confusing. For this to work, React Query needs to know about "freshness" / "staleness", but that is a property of Observers, not the Query itself. If you call queryClient.prefetchQuery({ queryKey, queryFn }) without explicitly passing staleTime, the default one will be taken. If you haven't set a global default staleTime, the default of zero will always trigger a new fetch with prefetchQuery, even if there is data in the cache.

When we prefetch, we usually don't have an active Observer via useQuery. So even if we set staleTime on our useQuery call, by the time we call prefetchQuery, the default is still used. I think this is worth pointing out.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Excellent point! I copied this from the old docs and didn't think much about it, should be fixed now.

- If a `staleTime` is passed eg. `prefetchQuery({ queryKey: ['todos'], queryFn: fn, staleTime: 5000 })` and the data is older than the specified `staleTime`, the query will be fetched
- (If you want to ignore `staleTime` and instead always return data if it's available in the cache, you can use the `ensureQueryData` function.)
- If no instances of `useQuery` appear for a prefetched query, it will be deleted and garbage collected after the time specified in `gcTime`
- These functions does not return the query data. If that's something you need, use `fetchQuery`/`fetchInfiniteQuery` instead.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
- These functions does not return the query data. If that's something you need, use `fetchQuery`/`fetchInfiniteQuery` instead.
- These functions do not return the query data. If that's something you need, use `fetchQuery`/`fetchInfiniteQuery` instead.

I would also point out that a Promise<void> is returned so that it can be awaited, but it will never throw errors (so you don't need try/catch).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh yeah! The error one has bit even me in the past, glad you pointed it out. Fixed.

Comment on lines 66 to 74
const prefetch = useCallback(() => {
queryClient.prefetchQuery({
queryKey: ['details'],
queryFn: getDetailsData,
// Prefetch only fires when data is older than the staleTime,
// so in a case like this you definitely want to set one
staleTime: 60000,
})
}, [queryClient])
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we skip the wrapping in useCallback ? Having it in the docs feels like its required to do it, but it's not. We pass that event handler to a built-in <button> component, so it doesn't matter if it's a new function on every render.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point, fixed!

docs/react/guides/prefetching.md Outdated Show resolved Hide resolved
Comment on lines 136 to 140
// Prefetch
useQuery({
queryKey: ['article-comments', id],
queryFn: getArticleCommentsById,
})
Copy link
Collaborator

Choose a reason for hiding this comment

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

another optimization we could point out that even if we ignore the result of useQuery, we still have an active observer that is subscribed to all changes of that query, so we will get a bunch of re-renders of this component even though it's not really necessary.

This is a technical limitation of how property tracking works: If you "use" no property during rendering, you "use" all of them because you could potentially access them in effects or event handlers.

To avoid this, we can pass notifyOnChangeProps: [] to this useQuery:

  // Prefetch
  useQuery({
    queryKey: ['article-comments', id],
    queryFn: getArticleCommentsById,
    notifyOnChangeProps: []
  })

This might even be a valid enough use-case to have a usePrefetchQuery hook that returns nothing 🤔 ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nice one, added! Didn't know about that myself actually.

Yeah, I think there is a strong argument for adding that, it also encourages prefetching which is nice. If we add it, let's make sure it matches any fetch/read API for the suspense side of things. We could probably have just one common prefetch hook for both.

docs/react/guides/prefetching.md Outdated Show resolved Hide resolved
docs/react/guides/prefetching.md Show resolved Hide resolved
@Ephem Ephem marked this pull request as ready for review September 22, 2023 18:16
@Ephem Ephem changed the title WIP: SSR docs rewrite SSR docs rewrite Sep 22, 2023
@Ephem
Copy link
Collaborator Author

Ephem commented Sep 22, 2023

Phew, I need to re-read this during the weekend, but it should be ready for review now. It might not be perfect, but I hope it's better than the current docs at least.

I'd love high level feedback as well. Are the pages too long/verbose/tries to cover too much? Are there sections we could skip or are there sections we should add? Also, I've made a few "official recommendations" in there, do you agree with them? I am biased towards prefetching, does that shine through too much? What about the naming of the guides, specifically, should we call the "Advanced Server Rendering" guide "Server Components & Streaming" instead?

Finally, this messes up the Vue docs for prefetching since those are just copied from the React docs, and there are now React specific things in there. I wont have time to fix this properly right now, do you want me to just copy the old doc over into the Vue docs folder in this PR?

Copy link
Collaborator

@TkDodo TkDodo left a comment

Choose a reason for hiding this comment

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

wonderfully written ❤️

docs/react/guides/prefetching.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
@TkDodo TkDodo changed the base branch from beta to rc September 25, 2023 08:27
Copy link
Collaborator Author

@Ephem Ephem left a comment

Choose a reason for hiding this comment

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

Super valuable feedback @TkDodo, thanks so much! I'll tackle it right away.

docs/react/guides/prefetching.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Outdated Show resolved Hide resolved
docs/react/guides/ssr.md Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
docs/react/guides/advanced-ssr.md Outdated Show resolved Hide resolved
@Ephem
Copy link
Collaborator Author

Ephem commented Sep 25, 2023

I think I managed to fix all your feedback @TkDodo, I resolved the minor stuff directly but left the comments about clarifications/reformulations open for you to look at. 😄

@TkDodo TkDodo merged commit 6e238af into TanStack:rc Sep 26, 2023
9 checks passed
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

2 participants