Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(query-core): add query() and infiniteQuery() methods#9835
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
6dd8fbfc824b114f5f27ac7bea26269ed8ef0217b419b13cf311b3bafd8ea67058fd5ca2c989ba78d0fede3f12d1ed58515c40184bf1511388d795ba905c54f89cc80fedf7b5a743447c7baef70c6ea773b0207d984739c08882abc141fe98c0029709c7acd3e6d373d9f05ccce4dcb66c25c3c4d70a4221be54ac44375abbdad0af6f4df243b553acf7b2526ccd459fff81d964547d46862fecd8c3b75c9f7020f9fd7628e7a2a7f47d9ba246afbda6289bce2466e0b0f4d63b7a0e13d4fda1643b65800ee296a8a3f9d4ec0c4f963e3858e6dbeb06de5d2e6abcd306b2864569861992bc1f49a8b9efa4a5315912e999ca6d55fd03aee483d5c473f6acab4e1a3dca76b23b35ecf6a7f415be0b74c7e508126648cba588963801c3ac2ac8213a85d261b7a0531d3fd03f6bf0f87217817443d751b6cda2cd69aa9646f3ac9d46b8e68dacdb04ea421496ac419f9686d15c60d5cf0e8263238fab00e6d6File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@tanstack/query-core': minor | ||
| '@tanstack/solid-query': minor | ||
| '@tanstack/vue-query': minor | ||
| '@tanstack/preact-query': minor | ||
| '@tanstack/react-query': minor | ||
| --- | ||
| add query() and infiniteQuery() imperative methods to QueryClient | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -7,7 +7,7 @@ ref: docs/framework/react/guides/query-options.md | ||
| [//]: # 'Example1' | ||
| ```ts | ||
| import { queryOptions } from '@tanstack/angular-query-experimental' | ||
| import { queryOptions, noop } from '@tanstack/angular-query-experimental' | ||
| @Injectable({ | ||
| providedIn: 'root', | ||
| @@ -38,7 +38,7 @@ queries = inject(QueriesService) | ||
| postQuery = injectQuery(() => this.queries.post(this.postId())) | ||
| queryClient.prefetchQuery(this.queries.post(23)) | ||
| queryClient.query(this.queries.post(23)).catch(noop) | ||
coderabbitai[bot] marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| queryClient.setQueryData(this.queries.post(42).queryKey, newPost) | ||
| ``` | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -116,10 +116,12 @@ import { | ||
| export async function getStaticProps() { | ||
| const queryClient = new QueryClient() | ||
| await queryClient.prefetchQuery({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| await queryClient | ||
| .query({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| .catch(noop) | ||
DogPawHat marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| return { | ||
| props: { | ||
| @@ -172,10 +174,12 @@ import Posts from './posts' | ||
| export default async function PostsPage() { | ||
| const queryClient = new QueryClient() | ||
| await queryClient.prefetchQuery({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| await queryClient | ||
| .query({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| .catch(noop) | ||
| return ( | ||
| // Neat! Serialization is now as easy as passing props. | ||
| @@ -237,10 +241,12 @@ import CommentsServerComponent from './comments-server' | ||
| export default async function PostsPage() { | ||
| const queryClient = new QueryClient() | ||
| await queryClient.prefetchQuery({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| await queryClient | ||
| .query({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| .catch(noop) | ||
| return ( | ||
| <HydrationBoundary state={dehydrate(queryClient)}> | ||
| @@ -261,10 +267,12 @@ import Comments from './comments' | ||
| export default async function CommentsServerComponent() { | ||
| const queryClient = new QueryClient() | ||
| await queryClient.prefetchQuery({ | ||
| queryKey: ['posts-comments'], | ||
| queryFn: getComments, | ||
| }) | ||
| await queryClient | ||
| .query({ | ||
| queryKey: ['posts-comments'], | ||
| queryFn: getComments, | ||
| }) | ||
| .catch(noop) | ||
| return ( | ||
| <HydrationBoundary state={dehydrate(queryClient)}> | ||
| @@ -325,8 +333,8 @@ import Posts from './posts' | ||
| export default async function PostsPage() { | ||
| const queryClient = new QueryClient() | ||
| // Note we are now using fetchQuery() | ||
| const posts = await queryClient.fetchQuery({ | ||
| // Note we are getting the result from query | ||
| const posts = await queryClient.query({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| @@ -355,7 +363,7 @@ Using React Query with Server Components makes most sense if: | ||
| It's hard to give general advice on when it makes sense to pair React Query with Server Components and not. **If you are just starting out with a new Server Components app, we suggest you start out with any tools for data fetching your framework provides you with and avoid bringing in React Query until you actually need it.** This might be never, and that's fine, use the right tool for the job! | ||
| If you do use it, a good rule of thumb is to avoid `queryClient.fetchQuery` unless you need to catch errors. If you do use it, don't render its result on the server or pass the result to another component, even a Client Component one. | ||
| If you do use it, a good rule of thumb is to avoid rendering the result of `queryClient.query` on the server or passing it to another component, even a Client Component one. | ||
| From the React Query perspective, treat Server Components as a place to prefetch data, nothing more. | ||
| @@ -424,7 +432,7 @@ export function getQueryClient() { | ||
| > Note: This works in NextJs and Server Components because React can serialize Promises over the wire when you pass them down to Client Components. | ||
| Then, all we need to do is provide a `HydrationBoundary`, but we don't need to `await` prefetches anymore: | ||
| Then, all we need to do is provide a `HydrationBoundary`, but we don't need to `await` these prefetches anymore: | ||
| ```tsx | ||
| // app/posts/page.tsx | ||
| @@ -437,10 +445,12 @@ export default function PostsPage() { | ||
| const queryClient = getQueryClient() | ||
| // look ma, no await | ||
| queryClient.prefetchQuery({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| void queryClient | ||
| .query({ | ||
| queryKey: ['posts'], | ||
| queryFn: getPosts, | ||
| }) | ||
| .catch(noop) | ||
| return ( | ||
| <HydrationBoundary state={dehydrate(queryClient)}> | ||
| @@ -504,10 +514,12 @@ export default function PostsPage() { | ||
| const queryClient = getQueryClient() | ||
| // look ma, no await | ||
| queryClient.prefetchQuery({ | ||
| queryKey: ['posts'], | ||
| queryFn: () => getPosts().then(serialize), // <-- serialize the data on the server | ||
| }) | ||
| void queryClient | ||
| .query({ | ||
| queryKey: ['posts'], | ||
| queryFn: () => getPosts().then(serialize), // <-- serialize the data on the server | ||
| }) | ||
| .catch(noop) | ||
| return ( | ||
| <HydrationBoundary state={dehydrate(queryClient)}> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -29,8 +29,6 @@ useIsMutating({ mutationKey, ...filters }) // [!code ++] | ||
| ```tsx | ||
| queryClient.isFetching(key, filters) // [!code --] | ||
| queryClient.isFetching({ queryKey, ...filters }) // [!code ++] | ||
| queryClient.ensureQueryData(key, filters) // [!code --] | ||
| queryClient.ensureQueryData({ queryKey, ...filters }) // [!code ++] | ||
| queryClient.getQueriesData(key, filters) // [!code --] | ||
| queryClient.getQueriesData({ queryKey, ...filters }) // [!code ++] | ||
| queryClient.setQueriesData(key, updater, filters, options) // [!code --] | ||
| @@ -45,14 +43,6 @@ queryClient.invalidateQueries(key, filters, options) // [!code --] | ||
| queryClient.invalidateQueries({ queryKey, ...filters }, options) // [!code ++] | ||
| queryClient.refetchQueries(key, filters, options) // [!code --] | ||
| queryClient.refetchQueries({ queryKey, ...filters }, options) // [!code ++] | ||
| queryClient.fetchQuery(key, fn, options) // [!code --] | ||
| queryClient.fetchQuery({ queryKey, queryFn, ...options }) // [!code ++] | ||
| queryClient.prefetchQuery(key, fn, options) // [!code --] | ||
| queryClient.prefetchQuery({ queryKey, queryFn, ...options }) // [!code ++] | ||
| queryClient.fetchInfiniteQuery(key, fn, options) // [!code --] | ||
| queryClient.fetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++] | ||
| queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --] | ||
| queryClient.prefetchInfiniteQuery({ queryKey, queryFn, ...options }) // [!code ++] | ||
| ``` | ||
| ```tsx | ||
| @@ -62,6 +52,39 @@ queryCache.findAll(key, filters) // [!code --] | ||
| queryCache.findAll({ queryKey, ...filters }) // [!code ++] | ||
| ``` | ||
| ### Imperative QueryClient methods | ||
| These methods are deprecated as of Tanstack Query `INSERT_FUTURE_V5_MINOR` and will be removed in v6. | ||
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I know this is a janky way of doing this. Open to suggestions or just saying "these methods are now deprecated" | ||
| If you are coming from v4 or earlier: | ||
| ```tsx | ||
| queryClient.fetchQuery(key, fn, options) // [!code --] | ||
| queryClient.query({ queryKey: key, queryFn: fn, ...options }) // [!code ++] | ||
| queryClient.fetchInfiniteQuery(key, fn, options) // [!code --] | ||
| queryClient.infiniteQuery({ | ||
| queryKey: key, | ||
| queryFn: fn, | ||
| ...options, | ||
| }) // [!code ++] | ||
| queryClient.prefetchQuery(key, fn, options) // [!code --] | ||
| queryClient.query({ queryKey: key, queryFn: fn, ...options }).catch(noop) // [!code ++] | ||
| queryClient.prefetchInfiniteQuery(key, fn, options) // [!code --] | ||
| queryClient | ||
| .infiniteQuery({ queryKey: key, queryFn: fn, ...options }) | ||
| .catch(noop) // [!code ++] | ||
| queryClient.ensureQueryData(key, options) // [!code --] | ||
| queryClient.query({ queryKey: key, ...options, staleTime: 'static' }) // [!code ++] | ||
| queryClient.ensureInfiniteQueryData(key, options) // [!code --] | ||
| queryClient.infiniteQuery({ queryKey: key, ...options, staleTime: 'static' }) // [!code ++] | ||
| ``` | ||
| If you are updating older v5 code, It will be the same as the above except for keeping the single options object | ||
DogPawHat marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| ### `queryClient.getQueryData` now accepts queryKey only as an Argument | ||
| `queryClient.getQueryData` argument is changed to accept only a `queryKey` | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.