Skip to content

Commit ce53f11

Browse files
committed
docs: restructure migration guide by importance of breaking changes
1 parent a46ba65 commit ce53f11

File tree

1 file changed

+117
-117
lines changed

1 file changed

+117
-117
lines changed

docs/src/pages/guides/migrating-to-react-query-4.md

Lines changed: 117 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ title: Migrating to React Query 4
55

66
## Breaking Changes
77

8-
### ESM Support
9-
10-
React Query now supports [package.json `"exports"`](https://nodejs.org/api/packages.html#exports) and is fully compatible with Node's native resolution for both CommonJS and ESM. We don't expect this to be a breaking change for most users, but this restricts the files you can import into your project to only the entry points we officially support.
11-
128
### Query Keys (and Mutation Keys) need to be an Array
139

1410
In v3, Query and Mutation Keys could be a String or an Array. Internally, React Query has always worked with Array Keys only, and we've sometimes exposed this to consumers. For example, in the `queryFn`, you would always get the key as an Array to make working with [Default Query Functions](./default-query-function) easier.
@@ -46,13 +42,58 @@ Please note in the case of `TypeScript` you need to use `tsx` as the parser othe
4642

4743
**Note:** Applying the codemod might break your code formatting, so please don't forget to run `prettier` and/or `eslint` after you've applied the codemod!
4844

49-
### Separate hydration exports have been removed
45+
### The idle state has been removed
5046

51-
With version [3.22.0](https://github.com/tannerlinsley/react-query/releases/tag/v3.22.0), hydration utilities moved into the React Query core. With v3, you could still use the old exports from `react-query/hydration`, but these exports have been removed with v4.
47+
With the introduction of the new [fetchStatus](../guides/queries#fetchstatus) for better offline support, the `idle` state became irrelevant, because `fetchStatus: 'idle'` captures the same state better. For more information, please read [Why two different states](../guides/queries#why-two-different-states).
48+
49+
This will mostly affect `disabled` queries that don't have any `data` yet, as those were in `idle` state before:
5250

5351
```diff
54-
- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration'
55-
+ import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query'
52+
- status: 'idle'
53+
+ status: 'loading'
54+
+ fetchStatus: 'idle'
55+
```
56+
57+
Also, have a look at [the guide on dependent queries](../guides/dependent-queries)
58+
59+
### new API for `useQueries`
60+
61+
The `useQueries` hook now accepts an object with a `queries` prop as its input. The value of the `queries` prop is an array of queries (this array is identical to what was passed into `useQueries` in v3).
62+
63+
```diff
64+
- useQueries([{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }])
65+
+ useQueries({ queries: [{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }] })
66+
```
67+
68+
### Undefined is an illegal cache value for successful queries
69+
70+
In order to make bailing out of updates possible by returning `undefined`, we had to make `undefined` an illegal cache value. This is in-line with other concepts of react-query, for example, returning `undefined` from the [initialData function](guides/initial-query-data#initial-data-function) will also _not_ set data.
71+
72+
Further, it is an easy bug to produce `Promise<void>` by adding logging in the queryFn:
73+
74+
```js
75+
useQuery(['key'], () => axios.get(url).then(result => console.log(result.data)))
76+
```
77+
78+
This is now disallowed on type level; at runtime, `undefined` will be transformed to a _failed Promise_, which means you will get an `error`, which will also be logged to the console in development mode.
79+
80+
### Queries and mutations, per default, need network connection to run
81+
82+
Please read the [New Features announcement](#proper-offline-support) about online / offline support, and also the dedicated page about [Network mode](../guides/network-mode)
83+
84+
Even though React Query is an Async State Manager that can be used for anything that produces a Promise, it is most often used for data fetching in combination with data fetching libraries. That is why, per default, queries and mutations will be `paused` if there is no network connection. If you want to opt-in to the previous behavior, you can globally set `networkMode: offlineFirst` for both queries and mutations:
85+
86+
```js
87+
new QueryClient({
88+
defaultOptions: {
89+
queries: {
90+
networkMode: 'offlineFirst',
91+
},
92+
mutations: {
93+
networkmode: 'offlineFirst',
94+
},
95+
},
96+
})
5697
```
5798

5899
### `notifyOnChangeProps` property no longer accepts `"tracked"` as a value
@@ -145,44 +186,6 @@ For the same reason, those have also been combined:
145186

146187
This flag defaults to `active` because `refetchActive` defaulted to `true`. This means we also need a way to tell `invalidateQueries` to not refetch at all, which is why a fourth option (`none`) is also allowed here.
147188

148-
### Streamlined NotifyEvents
149-
150-
Subscribing manually to the `QueryCache` has always given you a `QueryCacheNotifyEvent`, but this was not true for the `MutationCache`. We have streamlined the behavior and also adapted event names accordingly.
151-
152-
#### QueryCacheNotifyEvent
153-
154-
```diff
155-
- type: 'queryAdded'
156-
+ type: 'added'
157-
- type: 'queryRemoved'
158-
+ type: 'removed'
159-
- type: 'queryUpdated'
160-
+ type: 'updated'
161-
```
162-
163-
#### MutationCacheNotifyEvent
164-
165-
The `MutationCacheNotifyEvent` uses the same types as the `QueryCacheNotifyEvent`.
166-
167-
> Note: This is only relevant if you manually subscribe to the caches via `queryCache.subscribe` or `mutationCache.subscribe`
168-
169-
### The `src/react` directory was renamed to `src/reactjs`
170-
171-
Previously, React Query had a directory named `react` which imported from the `react` module. This could cause problems with some Jest configurations, resulting in errors when running tests like:
172-
173-
```
174-
TypeError: Cannot read property 'createContext' of undefined
175-
```
176-
177-
With the renamed directory this no longer is an issue.
178-
179-
If you were importing anything from `'react-query/react'` directly in your project (as opposed to just `'react-query'`), then you need to update your imports:
180-
181-
```diff
182-
- import { QueryClientProvider } from 'react-query/react';
183-
+ import { QueryClientProvider } from 'react-query/reactjs';
184-
```
185-
186189
### `onSuccess` is no longer called from `setQueryData`
187190

188191
This was confusing to many and also created infinite loops if `setQueryData` was called from within `onSuccess`. It was also a frequent source of error when combined with `staleTime`, because if data was read from the cache only, `onSuccess` was _not_ called.
@@ -216,112 +219,109 @@ Since these plugins are no longer experimental, their import paths have also bee
216219

217220
The [old `cancel` method](../guides/query-cancellation#old-cancel-function) that allowed you to define a `cancel` function on promises, which was then used by the library to support query cancellation, has been removed. We recommend to use the [newer API](../guides/query-cancellation) (introduced with v3.30.0) for query cancellation that uses the [`AbortController` API](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) internally and provides you with an [`AbortSignal` instance](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) for your query function to support query cancellation.
218221

219-
### Queries and mutations, per default, need network connection to run
222+
### TypeScript
220223

221-
Please read the [New Features announcement](#proper-offline-support) about online / offline support, and also the dedicated page about [Network mode](../guides/network-mode)
224+
Types now require using TypeScript v4.1 or greater
222225

223-
Even though React Query is an Async State Manager that can be used for anything that produces a Promise, it is most often used for data fetching in combination with data fetching libraries. That is why, per default, queries and mutations will be `paused` if there is no network connection. If you want to opt-in to the previous behavior, you can globally set `networkMode: offlineFirst` for both queries and mutations:
226+
### Supported Browsers
224227

225-
```js
226-
new QueryClient({
227-
defaultOptions: {
228-
queries: {
229-
networkMode: 'offlineFirst',
230-
},
231-
mutations: {
232-
networkmode: 'offlineFirst',
233-
},
234-
},
235-
})
236-
```
228+
As of v4, React Query is optimized for modern browsers. We have updated our browserslist to produce a more modern, performant and smaller bundle. You can read about the requirements [here](../installation#requirements).
237229

238-
### new API for `useQueries`
230+
### `setLogger` is removed
239231

240-
The `useQueries` hook now accepts an object with a `queries` prop as its input. The value of the `queries` prop is an array of queries (this array is identical to what was passed into `useQueries` in v3).
232+
It was possible to change the logger globally by calling `setLogger`. In v4, that function is replaced with an optional field when creating a `QueryClient`.
241233

242234
```diff
243-
- useQueries([{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }])
244-
+ useQueries({ queries: [{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }] })
245-
```
246-
247-
### Removed undocumented methods from the `queryClient`, `query` and `mutation`
248-
249-
The methods `cancelMutatations` and `executeMutation` on the `QueryClient` were undocumented and unused internally, so we removed them. Since it was just a wrapper around a method available on the `mutationCache`, you can still use the functionality of `executeMutation`
235+
- import { QueryClient, setLogger } from 'react-query';
236+
+ import { QueryClient } from 'react-query';
250237

251-
```diff
252-
- executeMutation<
253-
- TData = unknown,
254-
- TError = unknown,
255-
- TVariables = void,
256-
- TContext = unknown
257-
- >(
258-
- options: MutationOptions<TData, TError, TVariables, TContext>
259-
- ): Promise<TData> {
260-
- return this.mutationCache.build(this, options).execute()
261-
- }
238+
- setLogger(customLogger)
239+
- const queryClient = new QueryClient();
240+
+ const queryClient = new QueryClient({ logger: customLogger })
262241
```
263242

264-
Additionally, `query.setDefaultOptions` was removed because it was also unused. `mutation.cancel` was removed because it didn't actually cancel the outgoing request.
243+
### No _default_ manual Garbage Collection server-side
265244

266-
### TypeScript
245+
In v3, React Query would cache query results for a default of 5 minutes, then manually garbage collect that data. This default was applied to server-side React Query as well.
267246

268-
Types now require using TypeScript v4.1 or greater
247+
This lead to high memory consumption and hanging processes waiting for this manual garbage collection to complete. In v4, by default the server-side `cacheTime` is now set to `Infinity` effectively disabling manual garbage collection (the NodeJS process will clear everything once a request is complete).
248+
249+
This change only impacts users of server-side React Query, such as with Next.js. If you are setting a `cacheTime` manually this will not impact you (although you may want to mirror behavior).
269250

270251
### Logging in production
271252

272253
Starting with v4, react-query will no longer log errors (e.g. failed fetches) to the console in production mode, as this was confusing to many.
273254
Errors will still show up in development mode.
274255

275-
### `setLogger` is removed
256+
### ESM Support
276257

277-
It was possible to change the logger globally by calling `setLogger`. In v4, that function is replaced with an optional field when creating a `QueryClient`.
258+
React Query now supports [package.json `"exports"`](https://nodejs.org/api/packages.html#exports) and is fully compatible with Node's native resolution for both CommonJS and ESM. We don't expect this to be a breaking change for most users, but this restricts the files you can import into your project to only the entry points we officially support.
278259

279-
```diff
280-
- import { QueryClient, setLogger } from 'react-query';
281-
+ import { QueryClient } from 'react-query';
260+
### Streamlined NotifyEvents
282261

283-
- setLogger(customLogger)
284-
- const queryClient = new QueryClient();
285-
+ const queryClient = new QueryClient({ logger: customLogger })
286-
```
262+
Subscribing manually to the `QueryCache` has always given you a `QueryCacheNotifyEvent`, but this was not true for the `MutationCache`. We have streamlined the behavior and also adapted event names accordingly.
287263

288-
### Undefined is an illegal cache value for successful queries
264+
#### QueryCacheNotifyEvent
289265

290-
In order to make bailing out of updates possible by returning `undefined`, we had to make `undefined` an illegal cache value. This is in-line with other concepts of react-query, for example, returning `undefined` from the [initialData function](guides/initial-query-data#initial-data-function) will also _not_ set data.
266+
```diff
267+
- type: 'queryAdded'
268+
+ type: 'added'
269+
- type: 'queryRemoved'
270+
+ type: 'removed'
271+
- type: 'queryUpdated'
272+
+ type: 'updated'
273+
```
291274

292-
Further, it is an easy bug to produce `Promise<void>` by adding logging in the queryFn:
275+
#### MutationCacheNotifyEvent
293276

294-
```js
295-
useQuery(['key'], () => axios.get(url).then(result => console.log(result.data)))
296-
```
277+
The `MutationCacheNotifyEvent` uses the same types as the `QueryCacheNotifyEvent`.
297278

298-
This is now disallowed on type level; at runtime, `undefined` will be transformed to a _failed Promise_, which means you will get an `error`, which will also be logged to the console in development mode.
279+
> Note: This is only relevant if you manually subscribe to the caches via `queryCache.subscribe` or `mutationCache.subscribe`
299280
300-
### Supported Browsers
281+
### Separate hydration exports have been removed
301282

302-
As of v4, React Query is optimized for modern browsers. We have updated our browserslist to produce a more modern, performant and smaller bundle. You can read about the requirements [here](../installation#requirements).
283+
With version [3.22.0](https://github.com/tannerlinsley/react-query/releases/tag/v3.22.0), hydration utilities moved into the React Query core. With v3, you could still use the old exports from `react-query/hydration`, but these exports have been removed with v4.
303284

304-
### The idle state has been removed
285+
```diff
286+
- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration'
287+
+ import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query'
288+
```
305289

306-
With the introduction of the new [fetchStatus](../guides/queries#fetchstatus) for better offline support, the `idle` state became irrelevant, because `fetchStatus: 'idle'` captures the same state better. For more information, please read [Why two different states](../guides/queries#why-two-different-states).
290+
### Removed undocumented methods from the `queryClient`, `query` and `mutation`
307291

308-
This will mostly affect `disabled` queries that don't have any `data` yet, as those were in `idle` state before:
292+
The methods `cancelMutatations` and `executeMutation` on the `QueryClient` were undocumented and unused internally, so we removed them. Since it was just a wrapper around a method available on the `mutationCache`, you can still use the functionality of `executeMutation`
309293

310294
```diff
311-
- status: 'idle'
312-
+ status: 'loading'
313-
+ fetchStatus: 'idle'
295+
- executeMutation<
296+
- TData = unknown,
297+
- TError = unknown,
298+
- TVariables = void,
299+
- TContext = unknown
300+
- >(
301+
- options: MutationOptions<TData, TError, TVariables, TContext>
302+
- ): Promise<TData> {
303+
- return this.mutationCache.build(this, options).execute()
304+
- }
314305
```
315306

316-
Also, have a look at [the guide on dependent queries](../guides/dependent-queries)
307+
Additionally, `query.setDefaultOptions` was removed because it was also unused. `mutation.cancel` was removed because it didn't actually cancel the outgoing request.
317308

318-
### No _default_ manual Garbage Collection server-side
309+
### The `src/react` directory was renamed to `src/reactjs`
319310

320-
In v3, React Query would cache query results for a default of 5 minutes, then manually garbage collect that data. This default was applied to server-side React Query as well.
311+
Previously, React Query had a directory named `react` which imported from the `react` module. This could cause problems with some Jest configurations, resulting in errors when running tests like:
321312

322-
This lead to high memory consumption and hanging processes waiting for this manual garbage collection to complete. In v4, by default the server-side `cacheTime` is now set to `Infinity` effectively disabling manual garbage collection (the NodeJS process will clear everything once a request is complete).
313+
```
314+
TypeError: Cannot read property 'createContext' of undefined
315+
```
323316

324-
This change only impacts users of server-side React Query, such as with Next.js. If you are setting a `cacheTime` manually this will not impact you (although you may want to mirror behavior).
317+
With the renamed directory this no longer is an issue.
318+
319+
If you were importing anything from `'react-query/react'` directly in your project (as opposed to just `'react-query'`), then you need to update your imports:
320+
321+
```diff
322+
- import { QueryClientProvider } from 'react-query/react';
323+
+ import { QueryClientProvider } from 'react-query/reactjs';
324+
```
325325

326326
## New Features 🚀
327327

@@ -336,10 +336,6 @@ In v3, React Query has always fired off queries and mutations, but then taken th
336336

337337
With v4, React Query introduces a new `networkMode` to tackle all these issues. Please read the dedicated page about the new [Network mode](../guides/network-mode) for more information.
338338

339-
### Mutation Cache Garbage Collection
340-
341-
Mutations can now also be garbage collected automatically, just like queries. The default `cacheTime` for mutations is also set to 5 minutes.
342-
343339
### Tracked Queries per default
344340

345341
React Query defaults to "tracking" query properties, which should give you a nice boost in render optimization. The feature has existed since [v3.6.0](https://github.com/tannerlinsley/react-query/releases/tag/v3.6.0) and has now become the default behavior with v4.
@@ -354,6 +350,10 @@ queryClient.setQueryData(['todo', id], previousTodo =>
354350
)
355351
```
356352

353+
### Mutation Cache Garbage Collection
354+
355+
Mutations can now also be garbage collected automatically, just like queries. The default `cacheTime` for mutations is also set to 5 minutes.
356+
357357
### Custom Contexts for Multiple Providers
358358

359359
Custom contexts can now be specified to pair hooks with their matching `Provider`. This is critical when there may be multiple React Query `Provider` instances in the component tree, and you need to ensure your hook uses the correct `Provider` instance.

0 commit comments

Comments
 (0)