Skip to content

Commit ab75aed

Browse files
authored
Merge branch 'main' into solid-query-docs-fix-suspense-bug
2 parents 2c8265b + 01212de commit ab75aed

File tree

151 files changed

+2583
-5696
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+2583
-5696
lines changed

.github/workflows/ci.yml

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ on:
77
description: override release tag
88
required: false
99
push:
10-
branches: ['main', 'alpha', 'beta', 'rc', 'v4']
10+
branches: [main, alpha, beta, rc, v4]
1111

1212
concurrency:
1313
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
@@ -16,6 +16,10 @@ concurrency:
1616
env:
1717
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
1818

19+
permissions:
20+
contents: write
21+
id-token: write
22+
1923
jobs:
2024
test-and-publish:
2125
name: Test & Publish
@@ -42,7 +46,7 @@ jobs:
4246
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
4347
pnpm run cipublish
4448
env:
45-
GH_TOKEN: ${{ secrets.GH_TOKEN }}
49+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4650
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
4751
TAG: ${{ inputs.tag }}
4852
- name: Upload coverage to Codecov

.github/workflows/pr.yml

+5-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ concurrency:
1212
env:
1313
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
1414

15+
permissions:
16+
contents: read
17+
1518
jobs:
1619
test:
1720
name: Test
@@ -28,8 +31,8 @@ jobs:
2831
- name: Get base and head commits for `nx affected`
2932
uses: nrwl/nx-set-shas@v4
3033
with:
31-
main-branch-name: 'main'
32-
- name: Run Tests
34+
main-branch-name: main
35+
- name: Run Checks
3336
run: pnpm run test:pr --parallel=3
3437
- name: Stop Nx Agents
3538
if: ${{ always() }}

.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
link-workspace-packages=true
22
prefer-workspace-packages=true
3+
provenance=true

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v22.2.0
1+
22.4.0

.pnpmfile.cjs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
function readPackage(pkg, context) {
2+
3+
if (pkg.name === 'react-scripts' && pkg.version === '4.0.3') {
4+
delete pkg.dependencies['@typescript-eslint/eslint-plugin']
5+
delete pkg.dependencies['@typescript-eslint/parser']
6+
delete pkg.dependencies['babel-eslint']
7+
delete pkg.dependencies['babel-jest']
8+
delete pkg.dependencies['eslint']
9+
delete pkg.dependencies['eslint-config-react-app']
10+
delete pkg.dependencies['eslint-plugin-flowtype']
11+
delete pkg.dependencies['eslint-plugin-import']
12+
delete pkg.dependencies['eslint-plugin-jest']
13+
delete pkg.dependencies['eslint-plugin-jsx-a11y']
14+
delete pkg.dependencies['eslint-plugin-react']
15+
delete pkg.dependencies['eslint-plugin-react-hooks']
16+
delete pkg.dependencies['eslint-plugin-testing-library']
17+
delete pkg.dependencies['jest']
18+
delete pkg.dependencies['jest-circus']
19+
delete pkg.dependencies['jest-resolve']
20+
delete pkg.dependencies['jest-watch-typeahead']
21+
context.log('Removed unused dependencies from [email protected]')
22+
}
23+
24+
25+
if (pkg.name === 'react-scripts' && pkg.version === '5.0.1') {
26+
delete pkg.dependencies['babel-jest']
27+
delete pkg.dependencies['eslint']
28+
delete pkg.dependencies['eslint-config-react-app']
29+
delete pkg.dependencies['jest']
30+
delete pkg.dependencies['jest-resolve']
31+
delete pkg.dependencies['jest-watch-typeahead']
32+
context.log('Removed unused dependencies from [email protected]')
33+
}
34+
35+
return pkg
36+
}
37+
38+
module.exports = {
39+
hooks: {
40+
readPackage,
41+
},
42+
}

docs/framework/react/comparison.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Feature/Capability Key:
3636
| Infinite Queries |||| 🛑 | 🛑 |
3737
| Bi-directional Infinite Queries || 🔶 | 🔶 | 🛑 | 🛑 |
3838
| Infinite Query Refetching ||| 🛑 | 🛑 | 🛑 |
39-
| Lagged Query Data<sup>1</sup> ||| 🛑 |||
39+
| Lagged Query Data<sup>1</sup> ||| |||
4040
| Selectors || 🛑 ||| N/A |
4141
| Initial Data ||||||
4242
| Scroll Recovery ||||||
@@ -48,15 +48,15 @@ Feature/Capability Key:
4848
| Offline Mutation Support || 🛑 | 🟡 | 🛑 | 🛑 |
4949
| Prefetching APIs ||||||
5050
| Query Cancellation || 🛑 | 🛑 | 🛑 ||
51-
| Partial Query Matching<sup>3</sup> || 🔶 | 🛑 || N/A |
51+
| Partial Query Matching<sup>3</sup> || 🔶 | || N/A |
5252
| Stale While Revalidate ||||| 🛑 |
5353
| Stale Time Configuration || 🛑<sup>7</sup> | 🛑 || 🛑 |
54-
| Pre-usage Query/Mutation Configuration<sup>4</sup> || 🛑 | 🛑 |||
54+
| Pre-usage Query/Mutation Configuration<sup>4</sup> || 🛑 | |||
5555
| Window Focus Refetching ||| 🛑 || 🛑 |
5656
| Network Status Refetching ||||| 🛑 |
5757
| General Cache Dehydration/Rehydration || 🛑 ||||
5858
| Offline Caching || 🛑 || 🔶 | 🛑 |
59-
| React Suspense ||| 🛑 | 🛑 ||
59+
| React Suspense ||| | 🛑 ||
6060
| Abstracted/Agnostic Core || 🛑 ||| 🛑 |
6161
| Automatic Refetch after Mutation<sup>5</sup> | 🔶 | 🔶 ||||
6262
| Normalized Caching<sup>6</sup> | 🛑 | 🛑 || 🛑 | 🛑 |

docs/framework/react/guides/advanced-ssr.md

+25-5
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,9 @@ With the prefetching patterns described above, React Query is perfectly compatib
365365

366366
As of React Query v5.40.0, you don't have to `await` all prefetches for this to work, as `pending` Queries can also be dehydrated and sent to the client. This lets you kick off prefetches as early as possible without letting them block an entire Suspense boundary, and streams the _data_ to the client as the query finishes. This can be useful for example if you want to prefetch some content that is only visible after some user interaction, or say if you want to `await` and render the first page of an infinite query, but start prefetching page 2 without blocking rendering.
367367

368-
To make this work, we have to instruct the `queryClient` to also `dehydrate` pending Queries. We can do this globally, or by passing that option directly to `hydrate`:
368+
To make this work, we have to instruct the `queryClient` to also `dehydrate` pending Queries. We can do this globally, or by passing that option directly to `hydrate`.
369+
370+
We will also need to move the `getQueryClient()` function out of our `app/providers.jsx` file as we want to use it in our server component and our client provider.
369371

370372
```tsx
371373
// app/get-query-client.ts
@@ -378,15 +380,30 @@ function makeQueryClient() {
378380
staleTime: 60 * 1000,
379381
},
380382
dehydrate: {
381-
// per default, only successful Queries are included,
382-
// this includes pending Queries as well
383+
// include pending queries in dehydration
383384
shouldDehydrateQuery: (query) =>
384385
defaultShouldDehydrateQuery(query) ||
385386
query.state.status === 'pending',
386387
},
387388
},
388389
})
389390
}
391+
392+
let browserQueryClient: QueryClient | undefined = undefined
393+
394+
export function getQueryClient() {
395+
if (isServer) {
396+
// Server: always make a new query client
397+
return makeQueryClient()
398+
} else {
399+
// Browser: make a new query client if we don't already have one
400+
// This is very important, so we don't re-make a new client if React
401+
// suspends during the initial render. This may not be needed if we
402+
// have a suspense boundary BELOW the creation of the query client
403+
if (!browserQueryClient) browserQueryClient = makeQueryClient()
404+
return browserQueryClient
405+
}
406+
}
390407
```
391408

392409
> Note: This works in NextJs and Server Components because React can serialize Promises over the wire when you pass them down to Client Components.
@@ -439,7 +456,7 @@ If you're using non-JSON data types and serialize the query results on the serve
439456
import { QueryClient, defaultShouldDehydrateQuery } from '@tanstack/react-query'
440457
import { deserialize, serialize } from './transformer'
441458

442-
export function makeQueryClient() {
459+
function makeQueryClient() {
443460
return new QueryClient({
444461
defaultOptions: {
445462
// ...
@@ -452,6 +469,8 @@ export function makeQueryClient() {
452469
},
453470
})
454471
}
472+
473+
// ...
455474
```
456475

457476
```tsx
@@ -461,11 +480,12 @@ import {
461480
HydrationBoundary,
462481
QueryClient,
463482
} from '@tanstack/react-query'
483+
import { getQueryClient } from './get-query-client'
464484
import { serialize } from './transformer'
465485
import Posts from './posts'
466486

467487
export default function PostsPage() {
468-
const queryClient = new QueryClient()
488+
const queryClient = getQueryClient()
469489

470490
// look ma, no await
471491
queryClient.prefetchQuery({

docs/framework/react/reference/useMutationState.md

+28
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,34 @@ const data = useMutationState({
3838
})
3939
```
4040

41+
**Example 3: Access the latest mutation data via the `mutationKey`**
42+
Each invocation of `mutate` adds a new entry to the mutation cache for `gcTime` milliseconds.
43+
44+
To access the latest invocation, you can check for the last item that `useMutationState` returns.
45+
46+
```tsx
47+
import { useMutation, useMutationState } from '@tanstack/react-query'
48+
49+
const mutationKey = ['posts']
50+
51+
// Some mutation that we want to get the state for
52+
const mutation = useMutation({
53+
mutationKey,
54+
mutationFn: (newPost) => {
55+
return axios.post('/posts', newPost)
56+
},
57+
})
58+
59+
const data = useMutationState({
60+
// this mutation key needs to match the mutation key of the given mutation (see above)
61+
filters: { mutationKey },
62+
select: (mutation) => mutation.state.data,
63+
})
64+
65+
// Latest mutation data
66+
const latest = data[data.length - 1]
67+
```
68+
4169
**Options**
4270

4371
- `options`

docs/reference/QueryClient.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Its available methods are:
6262
- `defaultOptions?: DefaultOptions`
6363
- Optional
6464
- Define defaults for all queries and mutations using this queryClient.
65-
- You can also define defaults to be used for [hydration](../../framework/react/reference/hydration.md)
65+
- You can also define defaults to be used for [hydration](../../framework/react/reference/hydration)
6666

6767
## `queryClient.fetchQuery`
6868

examples/angular/basic/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@angular/core": "^17.3.10",
1515
"@angular/platform-browser": "^17.3.10",
1616
"@angular/platform-browser-dynamic": "^17.3.10",
17-
"@tanstack/angular-query-experimental": "^5.50.2",
17+
"@tanstack/angular-query-experimental": "^5.51.4",
1818
"rxjs": "^7.8.1",
1919
"tslib": "^2.6.2",
2020
"zone.js": "^0.14.6"
@@ -23,7 +23,7 @@
2323
"@angular-devkit/build-angular": "^17.3.8",
2424
"@angular/cli": "^17.3.8",
2525
"@angular/compiler-cli": "^17.3.10",
26-
"@tanstack/angular-query-devtools-experimental": "^5.50.2",
26+
"@tanstack/angular-query-devtools-experimental": "^5.51.4",
2727
"typescript": "5.3.3"
2828
}
2929
}

examples/angular/infinite-query-with-max-pages/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"@angular/core": "^17.3.10",
1515
"@angular/platform-browser": "^17.3.10",
1616
"@angular/platform-browser-dynamic": "^17.3.10",
17-
"@tanstack/angular-query-experimental": "^5.50.2",
17+
"@tanstack/angular-query-experimental": "^5.51.4",
1818
"rxjs": "^7.8.1",
1919
"tslib": "^2.6.2",
2020
"zone.js": "^0.14.6"
@@ -23,7 +23,7 @@
2323
"@angular-devkit/build-angular": "^17.3.8",
2424
"@angular/cli": "^17.3.8",
2525
"@angular/compiler-cli": "^17.3.10",
26-
"@tanstack/angular-query-devtools-experimental": "^5.50.2",
26+
"@tanstack/angular-query-devtools-experimental": "^5.51.4",
2727
"typescript": "5.3.3"
2828
}
2929
}

examples/angular/router/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@angular/platform-browser": "^17.3.10",
1616
"@angular/platform-browser-dynamic": "^17.3.10",
1717
"@angular/router": "^17.3.10",
18-
"@tanstack/angular-query-experimental": "^5.50.2",
18+
"@tanstack/angular-query-experimental": "^5.51.4",
1919
"rxjs": "^7.8.1",
2020
"tslib": "^2.6.2",
2121
"zone.js": "^0.14.6"
@@ -24,7 +24,7 @@
2424
"@angular-devkit/build-angular": "^17.3.8",
2525
"@angular/cli": "^17.3.8",
2626
"@angular/compiler-cli": "^17.3.10",
27-
"@tanstack/angular-query-devtools-experimental": "^5.50.2",
27+
"@tanstack/angular-query-devtools-experimental": "^5.51.4",
2828
"typescript": "5.3.3"
2929
}
3030
}

examples/angular/simple/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"@angular/platform-browser": "^17.3.10",
1616
"@angular/platform-browser-dynamic": "^17.3.10",
1717
"@angular/router": "^17.3.10",
18-
"@tanstack/angular-query-experimental": "^5.50.2",
18+
"@tanstack/angular-query-experimental": "^5.51.4",
1919
"rxjs": "^7.8.1",
2020
"tslib": "^2.6.2",
2121
"zone.js": "^0.14.6"
@@ -24,7 +24,7 @@
2424
"@angular-devkit/build-angular": "^17.3.8",
2525
"@angular/cli": "^17.3.8",
2626
"@angular/compiler-cli": "^17.3.10",
27-
"@tanstack/angular-query-devtools-experimental": "^5.50.2",
27+
"@tanstack/angular-query-devtools-experimental": "^5.51.4",
2828
"typescript": "5.3.3"
2929
}
3030
}

examples/react/algolia/package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@
1111
"dependencies": {
1212
"@algolia/client-search": "4.23.3",
1313
"@algolia/transporter": "4.23.3",
14-
"@tanstack/react-query": "^5.50.1",
15-
"@tanstack/react-query-devtools": "^5.50.1",
14+
"@tanstack/react-query": "^5.51.4",
15+
"@tanstack/react-query-devtools": "^5.51.4",
1616
"algoliasearch": "4.23.3",
1717
"react": "19.0.0-rc-4c2e457c7c-20240522",
1818
"react-dom": "19.0.0-rc-4c2e457c7c-20240522"
1919
},
2020
"devDependencies": {
21-
"@tanstack/eslint-plugin-query": "^5.50.1",
21+
"@tanstack/eslint-plugin-query": "^5.51.1",
2222
"@types/react": "^18.2.79",
2323
"@types/react-dom": "^18.2.25",
24-
"@vitejs/plugin-react": "^4.2.1",
24+
"@vitejs/plugin-react": "^4.3.1",
2525
"typescript": "5.3.3",
26-
"vite": "^5.2.11"
26+
"vite": "^5.3.3"
2727
}
2828
}

examples/react/auto-refetching/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.50.1",
12-
"@tanstack/react-query-devtools": "^5.50.1",
11+
"@tanstack/react-query": "^5.51.4",
12+
"@tanstack/react-query-devtools": "^5.51.4",
1313
"next": "^14.2.4",
1414
"react": "^18.2.0",
1515
"react-dom": "^18.2.0"

examples/react/basic-graphql-request/package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
"preview": "vite preview"
99
},
1010
"dependencies": {
11-
"@tanstack/react-query": "^5.50.1",
12-
"@tanstack/react-query-devtools": "^5.50.1",
11+
"@tanstack/react-query": "^5.51.4",
12+
"@tanstack/react-query-devtools": "^5.51.4",
1313
"graphql": "^16.8.1",
1414
"graphql-request": "^7.0.1",
1515
"react": "19.0.0-rc-4c2e457c7c-20240522",
1616
"react-dom": "19.0.0-rc-4c2e457c7c-20240522"
1717
},
1818
"devDependencies": {
19-
"@vitejs/plugin-react": "^4.2.1",
20-
"vite": "^5.2.11"
19+
"@vitejs/plugin-react": "^4.3.1",
20+
"vite": "^5.3.3"
2121
}
2222
}

0 commit comments

Comments
 (0)