From 7c0187e8ec869f03d45279bf11b29c1a043ba43e Mon Sep 17 00:00:00 2001 From: Dominik Dorfmeister Date: Tue, 23 Apr 2024 09:11:13 +0200 Subject: [PATCH] docs: fix syntax highlighting --- .../guides/migrating-to-react-query-4.md | 162 +++++++++--------- 1 file changed, 85 insertions(+), 77 deletions(-) diff --git a/docs/framework/react/guides/migrating-to-react-query-4.md b/docs/framework/react/guides/migrating-to-react-query-4.md index 1a078e0a0b..7ba6fa7d43 100644 --- a/docs/framework/react/guides/migrating-to-react-query-4.md +++ b/docs/framework/react/guides/migrating-to-react-query-4.md @@ -17,12 +17,12 @@ npm install @tanstack/react-query npm install @tanstack/react-query-devtools ``` -```diff -- import { useQuery } from 'react-query' -- import { ReactQueryDevtools } from 'react-query/devtools' +```tsx +- import { useQuery } from 'react-query' // [!code --] +- import { ReactQueryDevtools } from 'react-query/devtools' // [!code --] -+ import { useQuery } from '@tanstack/react-query' -+ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' ++ import { useQuery } from '@tanstack/react-query' // [!code ++] ++ import { ReactQueryDevtools } from '@tanstack/react-query-devtools' // [!code ++] ``` #### Codemod @@ -58,15 +58,15 @@ Please note in the case of `TypeScript` you need to use `tsx` as the parser; oth ### Query Keys (and Mutation Keys) need to be an Array -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](./guides/default-query-function) easier. +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. -However, we have not followed this concept through to all apis. For example, when using the `predicate` function on [Query Filters](./guides/filters) you would get the raw Query Key. This makes it difficult to work with such functions if you use Query Keys that are mixed Arrays and Strings. The same was true when using global callbacks. +However, we have not followed this concept through to all apis. For example, when using the `predicate` function on [Query Filters](../filters) you would get the raw Query Key. This makes it difficult to work with such functions if you use Query Keys that are mixed Arrays and Strings. The same was true when using global callbacks. To streamline all apis, we've decided to make all keys Arrays only: -```diff -- useQuery('todos', fetchTodos) -+ useQuery(['todos'], fetchTodos) +```tsx +;-useQuery('todos', fetchTodos) + // [!code --] + useQuery(['todos'], fetchTodos) // [!code ++] ``` #### Codemod @@ -100,41 +100,49 @@ Please note in the case of `TypeScript` you need to use `tsx` as the parser; oth ### The idle state has been removed -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). +With the introduction of the new [fetchStatus](../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](../queries#why-two-different-states). This will mostly affect `disabled` queries that don't have any `data` yet, as those were in `idle` state before: -```diff -- status: 'idle' -+ status: 'loading' -+ fetchStatus: 'idle' +```tsx +- status: 'idle' // [!code --] ++ status: 'loading' // [!code ++] ++ fetchStatus: 'idle' // [!code ++] ``` -Also, have a look at [the guide on dependent queries](./guides/dependent-queries) +Also, have a look at [the guide on dependent queries](../dependent-queries) #### disabled queries Due to this change, disabled queries (even temporarily disabled ones) will start in `loading` state. To make migration easier, especially for having a good flag to know when to display a loading spinner, you can check for `isInitialLoading` instead of `isLoading`: -```diff -- isLoading -+ isInitialLoading +```tsx +;-isLoading + // [!code --] + isInitialLoading // [!code ++] ``` -See also the guide on [disabling queries](./guides/disabling-queries#isInitialLoading) +See also the guide on [disabling queries](../disabling-queries#isInitialLoading) ### new API for `useQueries` 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). -```diff -- useQueries([{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }]) -+ useQueries({ queries: [{ queryKey1, queryFn1, options1 }, { queryKey2, queryFn2, options2 }] }) +```tsx +;-useQueries([ + { queryKey1, queryFn1, options1 }, + { queryKey2, queryFn2, options2 }, +]) + // [!code --] + useQueries({ + queries: [ + { queryKey1, queryFn1, options1 }, + { queryKey2, queryFn2, options2 }, + ], + }) // [!code ++] ``` ### Undefined is an illegal cache value for successful queries -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. +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](../initial-query-data#initial-data-function) will also _not_ set data. Further, it is an easy bug to produce `Promise` by adding logging in the queryFn: @@ -148,7 +156,7 @@ This is now disallowed on type level; at runtime, `undefined` will be transforme ### Queries and mutations, per default, need network connection to run -Please read the [New Features announcement](#proper-offline-support) about online / offline support, and also the dedicated page about [Network mode](./guides/network-mode) +Please read the [New Features announcement](#proper-offline-support) about online / offline support, and also the dedicated page about [Network mode](../network-mode) 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: @@ -209,7 +217,7 @@ queryClient.refetchQueries({ queryKey: ['todos'] }, { cancelRefetch: false }) ### Query Filters -A [query filter](./guides/filters) is an object with certain conditions to match a query. Historically, the filter options have mostly been a combination of boolean flags. However, combining those flags can lead to impossible states. Specifically: +A [query filter](../filters) is an object with certain conditions to match a query. Historically, the filter options have mostly been a combination of boolean flags. However, combining those flags can lead to impossible states. Specifically: ``` active?: boolean @@ -224,17 +232,17 @@ Those flags don't work well when used together, because they are mutually exclus With v4, those filters have been combined into a single filter to better show the intent: -```diff -- active?: boolean -- inactive?: boolean -+ type?: 'active' | 'inactive' | 'all' +```tsx +- active?: boolean // [!code --] +- inactive?: boolean // [!code --] ++ type?: 'active' | 'inactive' | 'all' // [!code ++] ``` The filter defaults to `all`, and you can choose to only match `active` or `inactive` queries. #### refetchActive / refetchInactive -[queryClient.invalidateQueries](./reference/QueryClient#queryclientinvalidatequeries) had two additional, similar flags: +[queryClient.invalidateQueries](../../../../reference/QueryClient/#queryclientinvalidatequeries) had two additional, similar flags: ``` refetchActive: Boolean @@ -249,10 +257,10 @@ refetchInactive: Boolean For the same reason, those have also been combined: -```diff -- refetchActive?: boolean -- refetchInactive?: boolean -+ refetchType?: 'active' | 'inactive' | 'all' | 'none' +```tsx +- refetchActive?: boolean // [!code --] +- refetchInactive?: boolean // [!code --] ++ refetchType?: 'active' | 'inactive' | 'all' | 'none' // [!code ++] ``` 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. @@ -272,23 +280,23 @@ React.useEffect(() => mySideEffectHere(data), [data]) ### `persistQueryClient` and the corresponding persister plugins are no longer experimental and have been renamed -The plugins `createWebStoragePersistor` and `createAsyncStoragePersistor` have been renamed to [`createSyncStoragePersister`](./plugins/createSyncStoragePersister) and [`createAsyncStoragePersister`](./plugins/createAsyncStoragePersister) respectively. The interface `Persistor` in `persistQueryClient` has also been renamed to `Persister`. Checkout [this stackexchange](https://english.stackexchange.com/questions/206893/persister-or-persistor) for the motivation of this change. +The plugins `createWebStoragePersistor` and `createAsyncStoragePersistor` have been renamed to [`createSyncStoragePersister`](../../plugins/createSyncStoragePersister) and [`createAsyncStoragePersister`](../../plugins/createAsyncStoragePersister) respectively. The interface `Persistor` in `persistQueryClient` has also been renamed to `Persister`. Checkout [this stackexchange](https://english.stackexchange.com/questions/206893/persister-or-persistor) for the motivation of this change. Since these plugins are no longer experimental, their import paths have also been updated: -```diff -- import { persistQueryClient } from 'react-query/persistQueryClient-experimental' -- import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental' -- import { createAsyncStoragePersistor } from 'react-query/createAsyncStoragePersistor-experimental' +```tsx +- import { persistQueryClient } from 'react-query/persistQueryClient-experimental' // [!code --] +- import { createWebStoragePersistor } from 'react-query/createWebStoragePersistor-experimental' // [!code --] +- import { createAsyncStoragePersistor } from 'react-query/createAsyncStoragePersistor-experimental' // [!code --] -+ import { persistQueryClient } from '@tanstack/react-query-persist-client' -+ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' -+ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' ++ import { persistQueryClient } from '@tanstack/react-query-persist-client' // [!code ++] ++ import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister' // [!code ++] ++ import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' // [!code ++] ``` ### The `cancel` method on promises is no longer supported -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. +The [old `cancel` method](../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](../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. ### TypeScript @@ -296,19 +304,19 @@ Types now require using TypeScript v4.1 or greater ### Supported Browsers -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). +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). ### `setLogger` is removed 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`. -```diff -- import { QueryClient, setLogger } from 'react-query'; -+ import { QueryClient } from '@tanstack/react-query'; +```tsx +- import { QueryClient, setLogger } from 'react-query'; // [!code --] ++ import { QueryClient } from '@tanstack/react-query'; // [!code ++] -- setLogger(customLogger) -- const queryClient = new QueryClient(); -+ const queryClient = new QueryClient({ logger: customLogger }) +- setLogger(customLogger) // [!code --] +- const queryClient = new QueryClient(); // [!code --] ++ const queryClient = new QueryClient({ logger: customLogger }) // [!code ++] ``` ### No _default_ manual Garbage Collection server-side @@ -334,13 +342,13 @@ Subscribing manually to the `QueryCache` has always given you a `QueryCacheNotif #### QueryCacheNotifyEvent -```diff -- type: 'queryAdded' -+ type: 'added' -- type: 'queryRemoved' -+ type: 'removed' -- type: 'queryUpdated' -+ type: 'updated' +```tsx +- type: 'queryAdded' // [!code --] ++ type: 'added' // [!code ++] +- type: 'queryRemoved' // [!code --] ++ type: 'removed' // [!code ++] +- type: 'queryUpdated' // [!code --] ++ type: 'updated' // [!code ++] ``` #### MutationCacheNotifyEvent @@ -353,26 +361,26 @@ The `MutationCacheNotifyEvent` uses the same types as the `QueryCacheNotifyEvent 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. -```diff -- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration' -+ import { dehydrate, hydrate, useHydrate, Hydrate } from '@tanstack/react-query' +```tsx +- import { dehydrate, hydrate, useHydrate, Hydrate } from 'react-query/hydration' // [!code --] ++ import { dehydrate, hydrate, useHydrate, Hydrate } from '@tanstack/react-query' // [!code ++] ``` ### Removed undocumented methods from the `queryClient`, `query` and `mutation` 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` -```diff -- executeMutation< -- TData = unknown, -- TError = unknown, -- TVariables = void, -- TContext = unknown -- >( -- options: MutationOptions -- ): Promise { -- return this.mutationCache.build(this, options).execute() -- } +```tsx +- executeMutation< // [!code --] +- TData = unknown, // [!code --] +- TError = unknown, // [!code --] +- TVariables = void, // [!code --] +- TContext = unknown // [!code --] +- >( // [!code --] +- options: MutationOptions // [!code --] +- ): Promise { // [!code --] +- return this.mutationCache.build(this, options).execute() // [!code --] +- } // [!code --] ``` Additionally, `query.setDefaultOptions` was removed because it was also unused. `mutation.cancel` was removed because it didn't actually cancel the outgoing request. @@ -389,9 +397,9 @@ With the renamed directory this no longer is an issue. 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: -```diff -- import { QueryClientProvider } from 'react-query/react'; -+ import { QueryClientProvider } from '@tanstack/react-query/reactjs'; +```tsx +- import { QueryClientProvider } from 'react-query/react'; // [!code --] ++ import { QueryClientProvider } from '@tanstack/react-query/reactjs'; // [!code ++] ``` ## New Features 🚀 @@ -411,7 +419,7 @@ In v3, React Query has always fired off queries and mutations, but then taken th - You are offline and want to fire off a query that doesn't necessarily need network connection (because you _can_ use React Query for something other than data fetching), but it fails for some other reason. That query will now be paused until you go online again. - Window focus refetching didn't do anything at all if you were offline. -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. +With v4, React Query introduces a new `networkMode` to tackle all these issues. Please read the dedicated page about the new [Network mode](../network-mode) for more information. ### Tracked Queries per default @@ -419,7 +427,7 @@ React Query defaults to "tracking" query properties, which should give you a nic ### Bailing out of updates with setQueryData -When using the [functional updater form of setQueryData](./reference/QueryClient#queryclientsetquerydata), you can now bail out of the update by returning `undefined`. This is helpful if `undefined` is given to you as `previousValue`, which means that currently, no cached entry exists and you don't want to / cannot create one, like in the example of toggling a todo: +When using the [functional updater form of setQueryData](../../../../reference/QueryClient/#queryclientsetquerydata), you can now bail out of the update by returning `undefined`. This is helpful if `undefined` is given to you as `previousValue`, which means that currently, no cached entry exists and you don't want to / cannot create one, like in the example of toggling a todo: ```tsx queryClient.setQueryData(['todo', id], (previousTodo) =>