Skip to content

Commit 8eb8d45

Browse files
committed
feat: initial v3 changes
1 parent e16f3dd commit 8eb8d45

Some content is hidden

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

69 files changed

+3909
-4054
lines changed

.github/workflows/test-and-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
registry-url: https://registry.npmjs.org/
3939
- name: Install dependencies
4040
uses: bahmutov/npm-install@v1
41-
- run: yarn build && yarn build:types
41+
- run: yarn build
4242
- run: npx semantic-release@17
4343
env:
4444
NODE_AUTH_TOKEN: ${{secrets.npm_token}}

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
node_modules
66

77
# builds
8+
types
89
build
910
dist
1011
lib
1112
es
1213
artifacts
1314
.rpt2_cache
1415
coverage
16+
*.tgz
1517

1618
# misc
1719
.DS_Store
@@ -31,5 +33,3 @@ stats-hydration.json
3133
stats-react.json
3234
stats.html
3335
.vscode/settings.json
34-
35-
types

core/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"internal": true,
3+
"main": "../lib/core/index.js",
4+
"module": "../es/core/index.js",
5+
"types": "../types/core/index.d.ts"
6+
}

docs/src/pages/docs/api.md

Lines changed: 310 additions & 371 deletions
Large diffs are not rendered by default.

docs/src/pages/docs/comparison.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Feature/Capability Key:
2828
| Paginated Queries ||||
2929
| Infinite Queries ||||
3030
| Lagged / "Lazy" Queries<sup>1</sup> || 🛑 | 🛑 |
31+
| Selectors || 🛑 ||
3132
| Initial Data ||||
3233
| Scroll Recovery ||||
3334
| Cache Manipulation ||||
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
---
2+
id: migrating-to-react-query-3
3+
title: Migrating to React Query 3
4+
---
5+
6+
## V3 migration
7+
8+
This article explains how to migrate your application to React Query 3.
9+
10+
### QueryClient
11+
12+
The `QueryCache` has been split into a `QueryClient` and a `QueryCache`.
13+
The `QueryCache` contains all cached queries and the `QueryClient` can be used to interact with a cache.
14+
15+
This has some benefits:
16+
17+
- Allows for different type of caches.
18+
- Multiple clients with different configurations can use the same cache.
19+
- Clients can be used to track queries, which can be used for shared caches on SSR.
20+
- The client API is more focused towards general usage.
21+
- Easier to test the individual components.
22+
23+
Use the `QueryClientProvider` component to connect a `QueryClient` to your application:
24+
25+
```js
26+
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
27+
28+
const cache = new QueryCache()
29+
const client = new QueryClient({ cache })
30+
31+
function App() {
32+
return <QueryClientProvider client={client}>...</QueryClientProvider>
33+
}
34+
```
35+
36+
### useQueryCache()
37+
38+
The `useQueryCache()` hook has been replaced by the `useQueryClient()` hook:
39+
40+
```js
41+
import { useCallback } from 'react'
42+
import { useQueryClient } from 'react-query'
43+
44+
function Todo() {
45+
const client = useQueryClient()
46+
47+
const onClickButton = useCallback(() => {
48+
client.invalidateQueries('posts')
49+
}, [client])
50+
51+
return <button onClick={onClickButton}>Refetch</button>
52+
}
53+
```
54+
55+
### ReactQueryConfigProvider
56+
57+
The `ReactQueryConfigProvider` component has been removed. Default options for queries and mutations can now be specified in `QueryClient`:
58+
59+
```js
60+
const client = new QueryClient({
61+
cache,
62+
defaultOptions: {
63+
queries: {
64+
staleTime: Infinity,
65+
},
66+
},
67+
})
68+
```
69+
70+
### usePaginatedQuery()
71+
72+
The `usePaginatedQuery()` hook has been replaced by the `keepPreviousData` option on `useQuery`:
73+
74+
```js
75+
import { useQuery } from 'react-query'
76+
77+
function Page({ page }) {
78+
const { data } = useQuery(['page', page], fetchPage, {
79+
keepPreviousData: true,
80+
})
81+
}
82+
```
83+
84+
### Query object syntax
85+
86+
The object syntax has been collapsed:
87+
88+
```js
89+
// Old:
90+
useQuery({
91+
queryKey: 'posts',
92+
queryFn: fetchPosts,
93+
config: { staleTime: Infinity },
94+
})
95+
96+
// New:
97+
useQuery({
98+
queryKey: 'posts',
99+
queryFn: fetchPosts,
100+
staleTime: Infinity,
101+
})
102+
```
103+
104+
### queryCache.prefetchQuery()
105+
106+
The `client.prefetchQuery()` method should now only be used for prefetching scenarios where the result is not relevant.
107+
108+
Use the `client.fetchQueryData()` method to get the query data or error:
109+
110+
```js
111+
// Prefetch a query:
112+
await client.prefetchQuery('posts', fetchPosts)
113+
114+
// Fetch a query:
115+
try {
116+
const data = await client.fetchQueryData('posts', fetchPosts)
117+
} catch (error) {
118+
// Error handling
119+
}
120+
```
121+
122+
### ReactQueryCacheProvider
123+
124+
The `ReactQueryCacheProvider` component has been replaced by the `QueryClientProvider` component.
125+
126+
### makeQueryCache()
127+
128+
The `makeQueryCache()` function has replaced by `new QueryCache()`.
129+
130+
### ReactQueryErrorResetBoundary
131+
132+
The `ReactQueryErrorResetBoundary` component has been renamed to `QueryErrorResetBoundary`.
133+
134+
### queryCache.resetErrorBoundaries()
135+
136+
The `queryCache.resetErrorBoundaries()` method has been replaced by the `QueryErrorResetBoundary` component.
137+
138+
### queryCache.getQuery()
139+
140+
The `queryCache.getQuery()` method has been replaced by `cache.find()`.
141+
142+
### queryCache.getQueries()
143+
144+
The `queryCache.getQueries()` method has been replaced by `cache.findAll()`.
145+
146+
### queryCache.isFetching
147+
148+
The `queryCache.isFetching` property has been replaced by `client.isFetching()`.
149+
150+
### QueryOptions.initialStale
151+
152+
The `initialStale` query option has been removed and initial data is now treated as regular data.
153+
Which means that if `initialData` is provided, the query will refetch on mount by default.
154+
If you do not want to refetch immediately, you can define a `staleTime`.
155+
156+
### QueryOptions.forceFetchOnMount
157+
158+
The `forceFetchOnMount` query option has been replaced by `refetchOnMount: 'always'`.
159+
160+
### QueryOptions.refetchOnMount
161+
162+
When `refetchOnMount` was set to `false` any additional components were prevented from refetching on mount.
163+
In version 3 only the component where the option has been set will not refetch on mount.
164+
165+
### QueryResult.clear()
166+
167+
The `QueryResult.clear()` method has been renamed to `QueryResult.remove()`.
168+
169+
### New features
170+
171+
Some new features have also been added besides the API changes, performance improvements and file size reduction.
172+
173+
#### Selectors
174+
175+
The `useQuery` and `useInfiniteQuery` hooks now have a `select` option to select or transform parts of the query result.
176+
177+
```js
178+
import { useQuery } from 'react-query'
179+
180+
function User() {
181+
const { data } = useQuery('user', fetchUser, {
182+
select: user => user.username,
183+
})
184+
return <div>Username: {data}</div>
185+
}
186+
```
187+
188+
Set the `notifyOnStatusChange` option to `false` to only re-render when the selected data changes.
189+
190+
#### useQueries()
191+
192+
The `useQueries()` hook can be used to fetch a variable number of queries:
193+
194+
```js
195+
import { useQueries } from 'react-query'
196+
197+
function Overview() {
198+
const results = useQueries([
199+
{ queryKey: ['post', 1], queryFn: fetchPost },
200+
{ queryKey: ['post', 2], queryFn: fetchPost },
201+
])
202+
return (
203+
<ul>
204+
{results.map(({ data }) => data && <li key={data.id}>{data.title})</li>)}
205+
</ul>
206+
)
207+
}
208+
```
209+
210+
#### client.watchQuery()
211+
212+
The `client.watchQuery()` method can be used to create and/or watch a query:
213+
214+
```js
215+
const observer = client.watchQuery('posts')
216+
217+
observer.subscribe(result => {
218+
console.log(result)
219+
observer.unsubscribe()
220+
})
221+
```
222+
223+
#### client.watchQueries()
224+
225+
The `client.watchQueries()` method can be used to create and/or watch multiple queries:
226+
227+
```js
228+
const observer = client.watchQueries([
229+
{ queryKey: ['post', 1], queryFn: fetchPost },
230+
{ queryKey: ['post', 2], queryFn: fetchPost },
231+
])
232+
233+
observer.subscribe(result => {
234+
console.log(result)
235+
observer.unsubscribe()
236+
})
237+
```
238+
239+
## `client.setQueryDefaults`
240+
241+
The `client.setQueryDefaults()` method to set default options for a specific query. If the query does not exist yet it will create it.
242+
243+
```js
244+
client.setQueryDefaults('posts', fetchPosts)
245+
246+
function Component() {
247+
const { data } = useQuery('posts')
248+
}
249+
```
250+
251+
#### React Native error screens
252+
253+
To prevent showing error screens in React Native when a query fails it was necessary to manually change the Console:
254+
255+
```js
256+
import { setConsole } from 'react-query'
257+
258+
setConsole({
259+
log: console.log,
260+
warn: console.warn,
261+
error: console.warn,
262+
})
263+
```
264+
265+
In version 3 this is done automatically when React Query is used in React Native.
266+
267+
#### Core separation
268+
269+
The core of React Query is now fully separated from React, which means it can also be used standalone or in other frameworks. Use the `react-query/core` entrypoint to only import the core functionality:
270+
271+
```js
272+
import { QueryClient } from 'react-query/core'
273+
```

docs/src/pages/docs/guides/queries.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,33 @@ function GlobalLoadingIndicator() {
257257
) : null
258258
}
259259
```
260+
261+
# Query Filters
262+
263+
Some methods within React Query accept a `QueryFilters` object. A query filter is an object with certain conditions to match a query with:
264+
265+
```js
266+
await client.refetchQueries({ active: true, inactive: true })
267+
await client.refetchQueries('posts', { active: true, inactive: true })
268+
```
269+
270+
A query filter object supports the following properties:
271+
272+
- `exact?: boolean`
273+
- If you don't want to search queries inclusively by query key, you can pass the `exact: true` option to return only the query with the exact query key you have passed.
274+
- `active?: boolean`
275+
- When set to `true` it will match active queries.
276+
- When set to `false` it will match inactive queries.
277+
- `inactive?: boolean`
278+
- When set to `true` it will match active queries.
279+
- When set to `false` it will match inactive queries.
280+
- `stale?: boolean`
281+
- When set to `true` it will match stale queries.
282+
- When set to `false` it will not match stale queries.
283+
- `fresh?: boolean`
284+
- When set to `true` it will match fresh queries.
285+
- When set to `false` it will not match fresh queries.
286+
- `predicate?: (query: Query) => boolean`
287+
- This predicate function will be called for every single query in the cache and be expected to return truthy for queries that are `found`.
288+
- `queryKey?: QueryKey`
289+
- Set this property to define a query key to match on.

docs/src/pages/docs/guides/suspense.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ In addition to queries behaving differently in suspense mode, mutations also beh
4747

4848
Whether you are using **suspense** or **useErrorBoundaries** in your queries, you will need a way to let queries know that you want to try again when re-rendering after some error occured.
4949

50-
Query errors can be reset with the `ReactQueryErrorResetBoundary` component or with the `useErrorResetBoundary` hook.
50+
Query errors can be reset with the `QueryErrorResetBoundary` component or with the `useQueryErrorResetBoundary` hook.
5151

5252
When using the component it will reset any query errors within the boundaries of the component:
5353

5454
```js
55-
import { ReactQueryErrorResetBoundary } from 'react-query'
55+
import { QueryErrorResetBoundary } from 'react-query'
5656
import { ErrorBoundary } from 'react-error-boundary'
5757

5858
const App: React.FC = () => (
59-
<ReactQueryErrorResetBoundary>
59+
<QueryErrorResetBoundary>
6060
{({ reset }) => (
6161
<ErrorBoundary
6262
onReset={reset}
@@ -70,18 +70,18 @@ const App: React.FC = () => (
7070
<Page />
7171
</ErrorBoundary>
7272
)}
73-
</ReactQueryErrorResetBoundary>
73+
</QueryErrorResetBoundary>
7474
)
7575
```
7676

77-
When using the hook it will reset any query errors within the closest `ReactQueryErrorResetBoundary`. If there is no boundary defined it will reset them globally:
77+
When using the hook it will reset any query errors within the closest `QueryErrorResetBoundary`. If there is no boundary defined it will reset them globally:
7878

7979
```js
80-
import { useErrorResetBoundary } from 'react-query'
80+
import { useQueryErrorResetBoundary } from 'react-query'
8181
import { ErrorBoundary } from 'react-error-boundary'
8282

8383
const App: React.FC = () => {
84-
const { reset } = useErrorResetBoundary()
84+
const { reset } = useQueryErrorResetBoundary()
8585
return (
8686
<ErrorBoundary
8787
onReset={reset}

0 commit comments

Comments
 (0)