Skip to content

Commit b84681f

Browse files
authored
v4 alpha (#3060)
* feat(hydration): remove hydration package (#2936) * V4: streamline cancel refetch (#2937) * feat: streamline cancelRefetch the following functions now default to true for cancelRefetch: - refetchQueries (+invalidateQueries, + resetQueries) - query.refetch - fetchNextPage (unchanged) - fetchPreviousPage (unchanged) * feat: streamline cancelRefetch make sure that refetchOnReconnect and refetchOnWindowFocus do not cancel already running requests * feat: streamline cancelRefetch update tests refetch and invalidate now both cancel previous queries, which is intended, so we get more calls to the queryFn in these cases * feat: streamline cancelRefetch add more tests for cancelRefetch behavior * feat: streamline cancelRefetch update docs and migration guide * feat: streamline cancelRefetch simplify conditions by moving the ?? true default down to fetch on observer level; all 3 callers (fetchNextPage, fetchPreviousPage and refetch) just pass their options down and adhere to this default; refetch also only has 3 callers: - refetch from useQuery, where we want the default - onOnline and onFocus, where we now explicitly pass false to keep the previous behavior and add more tests * feat: streamline cancelRefetch we always call this.fetch() with options, so we can just as well make the mandatory also, streamline signatures by destructing values that can't be forwarded (and use empty object as default value) in options and just spread the rest * feat: streamline cancelRefetch fix types for refetch it was accidentally made too wide and allowed all refetchFilters, like `predicate`; but with `refetch` on an obserserver, there is nothing to filter for, except the page, so that is what we need to accept via `RefetchPageFilters` * feat: streamline cancelRefetch refetch never took a queryKey as param - it is always bound to the observer * feat: better query filters (#2938) * fix: rename react directory to reactjs (#2884) * fix: rename react directory to reactjs the directory being named "react" causes an error with the moduleDirectories option from jest * fix: update package.json files to match the updated reactjs directory name * fix: change react test utils imports to match new directory name * docs(v4): add renamed reactjs details to migration guide Co-authored-by: Eddy Vinck <[email protected]> * feat: mutation cache duration (#2963) * feat: mutation cachetime stramline queryCache / mutationCache events by combining them into notifiable.ts * feat: mutation cachetime removable * feat: mutation cachetime add gc to mutations * feat: mutation cachetime streamline event types between queries and mutations * feat: mutation cachetime tests, and I forgot to implement optionalRemove, so make it abstract * feat: mutation cachetime replicate gc behavior from #2950 and add more tests * feat: mutation cachetime get test coverage back to 100% * feat: mutation cachetime docs * feat: mutation cachetime try to make tests more resilient * feat: mutation cachetime fix imports after merge conflict * refactor(persistQueryClient): Make persistQueryClient stable (#2961) * 🚚 Remove experimental from persist-query-client * 🚚 Rename persistor -> persister * ✏️ Fix Persistor -> Persister in imports * 🚚 Update name in rollup config * 🚚 Move createAsyncStoragePersister and createWebStoragePersister to stable version and rename persistor -> persister * 📝 Update documentation * 📝 Add migrating to v4 docs * Apply suggestions from code review Co-authored-by: Dominik Dorfmeister <[email protected]> * 2964 changes to on success callback (#2969) * feat(useQuery): onSuccess callback do not call onSuccess if update was done manually from setQueryData * feat(useQuery): onSuccess callback test that onSuccess is not called when setQueryData is used * feat(useQuery): onSuccess callback docs changes * feat(useQuery): onSuccess callback options spread is wrong - `updatedAt` is actually `dataUpdatedAt`. Oddly we didn't have a test, so I added one * 2919 query key array (#2988) * feat: query key array remove code that internally ensures that we get an Array, because it is now the expected interface, ensured by TypeScript * feat: query key array update tests to the new syntax * feat: query key array fix assertions, because there is no array wrapping happening internally anymore. The key you receive from the context is exactly the key you passed in * feat: query key array this test doesn't make much sense anymore * feat: query key array wrapping in an extra array doesn't yield the same results anymore since v4 because keys need to be an array * feat: query key array make docs adhere to new array key syntax * feat: query key array migration docs * feat(QueryObserver): track queries as default (#2987) * feat(Query Options): remove notifyOnChangePropsExclusion - remove related code from queryObserver - remove type def - remove related tests * docs(Query Options): update notifyOnChangePropsExclusion sections - remove from api references - add to v4 migration guide * feat(QueryObserver): "tracked" as default behavior - remove "tracked" completely if notifyOnChangeProps is not defined, behave as v3 "tracked" - add `notifyOnChangeProps: 'all' to opt out of the smart tracking TODO: Now that default behavior has changed, work out the failed tests. Which parts to change for current ones and possibly write new ones. * test(useQuery): adjust tests to pass for notifyOnChangeProps udpate * test(useInfiniteQuery): adjust tests to pass for notifyOnChangeProps udpate * test(QueryResetErrorBoundary): adjust tests to pass for notifyOnChangeProps udpate * refactor(QueryObserver): use nullish coalescing operator much cleaner than the negated if I started with * test(QueryResetErrorBoundary): remove "tracked" from test * revert: test(QueryResetErrorBoundary): adjust tests to pass for notifyOnChaneProps udpate This reverts commit a34b472. The changes are not necessary after PR #2993 fix. * refactor(QueryObserver): combine prop checks * docs(notifyOnChangeProps): update docs to reflect new api * refactor: Remove deprecated promise cancel (#2996) * 🔥 Remove the cancel method on promise for cancelling promise * ✅ Fix query client tests * ✅ Update query and useQuery tests * ✅ Update use infinite query tests * 📝 Update migartion guide * 🐛 Fix linking in documentation * 📝 Fix grammatical errors in docs Co-authored-by: Dominik Dorfmeister <[email protected]> * :refactor: Use abortSignal for query cancellation in InfiniteQueryBehavior * 🚨 Fix lint errors * ♻️ Move define signal property to a separate function Co-authored-by: Dominik Dorfmeister <[email protected]> * remove test that doesn't make sense anymore - we don't allow different falsy query keys now * 2927 offline queries (#3006) * feat(useQuery): offline queries remove defaultQueryObserverOptions because it is the same as defaultQueryOptions and we can just use that * feat(useQuery): offline queries setup dependent default values, to make it easier to work with them * feat(useQuery): offline queries basic changes to retryer: - pause the query before fetching depending upon networkMode - pause retries depending upon networkRetry * feat(useQuery): offline queries move networkRetry and networkMode defaults to the retryer creation, because we need the same for mutations * feat(useQuery): offline queries decouple focus and online manager: we're now informing caches of a focus when we're focussed, and about an online event if we come online; if the retryer continues, it can then decide to not fetch depending on our networkMode * feat(useQuery): offline queries expose isPaused on the queryResult and make sure isFetching is false when we are paused * feat(useQuery): offline queries knowing if we can fetch depends on if we are paused or not, as other conditions should apply also, rename options (not sure if that will stick though) * feat(useQuery): offline queries adjust existing tests for isPaused being exposed * feat(useQuery): offline queries fix existing test by setting options to emulate the previous behaviour, otherwise, with `mockNavigatorOnline` being set to false right from the start, the mutation would never fire off * feat(useQuery): offline queries adapt onOnline, onFocus tests to new behavior: they are now decoupled, and onOnline is always called even when not focused and vice versa. The retryer should make sure to not continue fetching if necessary * feat(useQuery): offline queries first test for networkMode * feat(useQuery): offline queries isFetching and isPaused are now derived and stored together in a fetchingState enum (idle, fetching, paused) * feat(useQuery): offline queries better networkMode api: online, always, offlineFirst (basically always but with paused retries) * feat(useQuery): offline queries more tests for networkMode: online * feat(useQuery): offline queries more tests for networkMode: online * feat(useQuery): offline queries tests for networkMode: always * feat(useQuery): offline queries fix tests that were influencing each other by using proper jest mocks for online and visibility state * add paused queries to the devtools.tsx * feat(useQuery): offline queries never stop pausing when continueFn is called. Initially, I only had this guard for when it's called from the outside, e.g. for onWindowFocus while still being offline, but we need this always because otherwise query cancellation can potentially continue a paused query * feat(useQuery): offline queries okay, pausing multiple times was a bad idea, continueFn() will be called eventually anyways * feat(useQuery): offline queries attempt at offline toggle button * feat(useQuery): offline queries different icons, padding, color * feat(useQuery): offline queries i messed up the icon order * feat(useQuery): offline queries guard against illegal state transitions: paused queries can unmount or get cancelled, in which case we shouldn't continue them, even if we dispatch the continue event * feat(useQuery): offline queries fix devtools tests, account for paused queries * Revert "feat(useQuery): offline queries" This reverts commit a647f64. * feat(useQuery): offline queries keep the do-not-start logic out of the run function, and thus out of promiseOrValue. if the promise has already been resolved in the meantime, e.g. because of a `cancel`, the run method will just do nothing, while the previous logic would've started to fetch * feat(useQuery): offline queries show inactive as higher priority than paused * feat(useQuery): offline queries make sure that optimistic results don't show an intermediate fetching state, but go opmistically to paused instead * feat(useQuery): offline queries real result needs to match optimistic result * feat(useQuery): offline queries stupid mistake * feat(useQuery): offline queries keep status color and status label in sync * feat(useQuery): offline queries make networkMode param mandatory for canFetch (and default to online internally) so that we can't screw that up again * feat(useQuery): offline queries make sure test "finishes" to avoid prints to the console if another test goes online again * feat(useQuery): offline queries move cancel function to the top, as it's no longer dependent on the promise since the `.cancel` function is gone; all we need is to abort the signal and reject the promise of the retryer * feat(useQuery): offline queries inline canContinue, because it's now only called if the query is in paused state anyways * feat(useQuery): offline queries avoid the impossible state by not calling config.onContinue for already resolved queries, as that would put them right into fetching state again, without actually fetching * feat(useQuery): offline queries let resolved querie continue, but don't put them in fetching state * feat(useQuery): offline queries fix merge conflict and invert condition because no-negated-condition * feat(useQuery): offline queries add test for abort signal consumed - different results expected for node < 15 where we don't have AbortController, thus can't consume the signal * feat(useQuery): offline queries online queries should not fetch if paused and we go online when cancelled and no refetchOnReconnect * feat(useQuery): offline queries gc test * feat(useQuery): offline queries offlineFirst test * feat(useQuery): offline queries mock useMediaQuery to get rid of unnecessary check in devtools - if window is defined, `matchMedia` is also defined * feat(useQuery): offline queries use a higher retryDelay to make test more stable, otherwise, it might start retrying before we "go offline" * feat(useQuery): offline queries improve devtools test: check if onClick props are being called * feat(useQuery): offline queries add devtools test for offline mock * feat(useQuery): offline queries offline mutations test * feat(useQuery): offline queries network mode docs (unfinished) * feat(useQuery): offline queries network mode docs * feat(useQuery): offline queries fix merge conflicts * refactor(queryClient): remove undocumented methods * fix: offline mutations fixes (#3051) * feat: offline mutations move reducer into Mutation class to avoid passing state (and options) around * feat: offline mutations optimistically set paused state depending on if we can fetch or not to avoid an intermediate state where we are loading but not paused * examples: fix query keys in basic examples because we need those for preview builds * fix(useMutation): make sure cacheCallbacks are always called even if the useMutation component unmounts and we have a cacheTime of 0; the fix was cherry-picked from the react-18 branch, where we also introduced this behavior * Feature/cachetime zero (#3054) * refactor: cacheTime-zero remove special handling for cacheTime: 0 and schedule a normal garbage collection for those queries. They will be eligible for gc after a setTimeout(0), but then they will only be optionally removed. This makes sure that paused queries are NOT gc'ed * refactor: cacheTime-zero remove special test "about online queries with cacheTime:0 should not fetch if paused and then unmounted". paused queries will now be kept until they continue, just like with every other query, unless query cancellation or abort signal was involved * refactor: cacheTime-zero adapt "remounting" test: if the same query with cacheTime 0 unmounts and remounts in the same cycle, the query will now be picked up and will not go to loading state again. I think this is okay * refactor: cacheTime-zero re-add instant query removal after fetching, because fetching via `queryClient.fetchQuery` will not remove the query otherwise, because the normal gc-mechanism now checks for `hadObservers` due to a suspense issue :/ * refactor: cacheTime-zero weird edge case: the previous logic was instantly removing the query _while_ it was still fetching, which is something we likely don't want. The data will stay in the currentQuery of the observer if the observer unsubscribes but still exists, and a new subscription will pick it up, unless the query was explicitly cancelled or the abort signal was consumed. * refactor: cacheTime-zero we need to wait a tick because even cacheTime 0 now waits at least a setTimeout(0) to be eligible for gc * refactor: cacheTime-zero schedule a new garbage collection after each new fetch; this won't do anything when you still have observers, but it fixes an edge case where prefetching took longer than the cacheTime, in which case the query was again never removed test needed adaption because we don't instantly remove, but deferred by a tick * refactor: cacheTime-zero stabilize test * refactor: cacheTime-zero apply a different suspense "workaround": do not garbage collect when fetching optimistically (done only by suspense) - gc will kick in once an observer subscribes; this will make sure we can still gc other fetches that don't have an observer consistently, like prefetching when the fetch takes longer than the gc time (which was leaking with the old workaround) * refactor: cacheTime-zero remove leftover * refactor: cacheTime-zero since every fetch triggers a new gc cycle, we don't need to do this in a loop anymore also, reset isFetchingOptimistic after every fetch * add publishing capabilities for alpha branch * fix(queryFilters): fetchStatus to queryFilters (#3061) Co-authored-by: Eddy <[email protected]> Co-authored-by: Eddy Vinck <[email protected]> Co-authored-by: Prateek Surana <[email protected]> Co-authored-by: Rene Dellefont <[email protected]> BREAKING CHANGE: new query filters, query key must be an array
1 parent ebf1e68 commit b84681f

File tree

127 files changed

+3126
-1409
lines changed

Some content is hidden

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

127 files changed

+3126
-1409
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
branches:
66
- 'master'
77
- 'next'
8+
- 'alpha'
89
- 'beta'
910
- '1.x'
1011
- '2.x'
@@ -36,7 +37,7 @@ jobs:
3637
name: 'Publish Module to NPM'
3738
needs: test
3839
# publish only when merged in master on original repo, not on PR
39-
if: github.repository == 'tannerlinsley/react-query' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/next' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/1.x' || github.ref == 'refs/heads/2.x')
40+
if: github.repository == 'tannerlinsley/react-query' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/next' || github.ref == 'refs/heads/alpha' || github.ref == 'refs/heads/beta' || github.ref == 'refs/heads/1.x' || github.ref == 'refs/heads/2.x')
4041
runs-on: ubuntu-latest
4142
steps:
4243
- uses: actions/checkout@v2
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/createAsyncStoragePersister/index.js",
4+
"module": "../es/createAsyncStoragePersister/index.js",
5+
"types": "../types/createAsyncStoragePersister/index.d.ts"
6+
}

createAsyncStoragePersistor-experimental/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.
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/createWebStoragePersister/index.js",
4+
"module": "../es/createWebStoragePersister/index.js",
5+
"types": "../types/createWebStoragePersister/index.d.ts"
6+
}

createWebStoragePersistor-experimental/package.json

Lines changed: 0 additions & 6 deletions
This file was deleted.

docs/src/manifests/manifest.json

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@
7575
"path": "/guides/query-functions",
7676
"editUrl": "/guides/query-functions.md"
7777
},
78+
{
79+
"title": "Network Mode",
80+
"path": "/guides/network-mode",
81+
"editUrl": "/guides/network-mode.md"
82+
},
7883
{
7984
"title": "Parallel Queries",
8085
"path": "/guides/parallel-queries",
@@ -204,6 +209,11 @@
204209
"title": "Migrating to React Query 3",
205210
"path": "/guides/migrating-to-react-query-3",
206211
"editUrl": "/guides/migrating-to-react-query-3.md"
212+
},
213+
{
214+
"title": "Migrating to React Query 4",
215+
"path": "/guides/migrating-to-react-query-4",
216+
"editUrl": "/guides/migrating-to-react-query-4.md"
207217
}
208218
]
209219
},
@@ -314,19 +324,19 @@
314324
"heading": true,
315325
"routes": [
316326
{
317-
"title": "persistQueryClient (Experimental)",
327+
"title": "persistQueryClient",
318328
"path": "/plugins/persistQueryClient",
319329
"editUrl": "/plugins/persistQueryClient.md"
320330
},
321331
{
322-
"title": "createWebStoragePersistor (Experimental)",
323-
"path": "/plugins/createWebStoragePersistor",
324-
"editUrl": "/plugins/createWebStoragePersistor.md"
332+
"title": "createWebStoragePersister",
333+
"path": "/plugins/createWebStoragePersister",
334+
"editUrl": "/plugins/createWebStoragePersister.md"
325335
},
326336
{
327-
"title": "createAsyncStoragePersistor (Experimental)",
328-
"path": "/plugins/createAsyncStoragePersistor",
329-
"editUrl": "/plugins/createAsyncStoragePersistor.md"
337+
"title": "createAsyncStoragePersister",
338+
"path": "/plugins/createAsyncStoragePersister",
339+
"editUrl": "/plugins/createAsyncStoragePersister.md"
330340
},
331341
{
332342
"title": "broadcastQueryClient (Experimental)",
@@ -442,4 +452,4 @@
442452
]
443453
}
444454
]
445-
}
455+
}

docs/src/pages/comparison.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Feature/Capability Key:
6464

6565
> **<sup>1</sup> Lagged Query Data** - React Query provides a way to continue to see an existing query's data while the next query loads (similar to the same UX that suspense will soon provide natively). This is extremely important when writing pagination UIs or infinite loading UIs where you do not want to show a hard loading state whenever a new query is requested. Other libraries do not have this capability and render a hard loading state for the new query (unless it has been prefetched), while the new query loads.
6666
67-
> **<sup>2</sup> Render Optimization** - React Query has excellent rendering performance. It will only re-render your components when a query is updated. For example because it has new data, or to indicate it is fetching. React Query also batches updates together to make sure your application only re-renders once when multiple components are using the same query. If you are only interested in the `data` or `error` properties, you can reduce the number of renders even more by setting `notifyOnChangeProps` to `['data', 'error']`. Set `notifyOnChangeProps: 'tracked'` to automatically track which fields are accessed and only re-render if one of them changes.
67+
> **<sup>2</sup> Render Optimization** - React Query has excellent rendering performance. By default, it will automatically track which fields are accessed and only re-render if one of them changes. If you would like to opt-out of this optimization, setting `notifyOnChangeProps` to `'all'` will re-render your components whenever the query is updated. For example because it has new data, or to indicate it is fetching. React Query also batches updates together to make sure your application only re-renders once when multiple components are using the same query. If you are only interested in the `data` or `error` properties, you can reduce the number of renders even more by setting `notifyOnChangeProps` to `['data', 'error']`.
6868
6969
> **<sup>3</sup> Partial query matching** - Because React Query uses deterministic query key serialization, this allows you to manipulate variable groups of queries without having to know each individual query-key that you want to match, eg. you can refetch every query that starts with `todos` in its key, regardless of variables, or you can target specific queries with (or without) variables or nested properties, and even use a filter function to only match queries that pass your specific conditions.
7070

docs/src/pages/guides/caching.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ This caching example illustrates the story and lifecycle of:
1616

1717
Let's assume we are using the default `cacheTime` of **5 minutes** and the default `staleTime` of `0`.
1818

19-
- A new instance of `useQuery('todos', fetchTodos)` mounts.
19+
- A new instance of `useQuery(['todos'], fetchTodos)` mounts.
2020
- Since no other queries have been made with this query + variable combination, this query will show a hard loading state and make a network request to fetch the data.
21-
- It will then cache the data using `'todos'` and `fetchTodos` as the unique identifiers for that cache.
21+
- It will then cache the data using `['todos']` as the unique identifiers for that cache.
2222
- The hook will mark itself as stale after the configured `staleTime` (defaults to `0`, or immediately).
23-
- A second instance of `useQuery('todos', fetchTodos)` mounts elsewhere.
23+
- A second instance of `useQuery(['todos'], fetchTodos)` mounts elsewhere.
2424
- Because this exact data exists in the cache from the first instance of this query, that data is immediately returned from the cache.
2525
- A background refetch is triggered for both queries (but only one request), since a new instance appeared on screen.
2626
- Both instances are updated with the new data if the fetch is successful
27-
- Both instances of the `useQuery('todos', fetchTodos)` query are unmounted and no longer in use.
27+
- Both instances of the `useQuery(['todos'], fetchTodos)` query are unmounted and no longer in use.
2828
- Since there are no more active instances of this query, a cache timeout is set using `cacheTime` to delete and garbage collect the query (defaults to **5 minutes**).
29-
- Before the cache timeout has completed another instance of `useQuery('todos', fetchTodos)` mounts. The query immediately returns the available cached value while the `fetchTodos` function is being run in the background to populate the query with a fresh value.
30-
- The final instance of `useQuery('todos', fetchTodos)` unmounts.
31-
- No more instances of `useQuery('todos', fetchTodos)` appear within **5 minutes**.
29+
- Before the cache timeout has completed another instance of `useQuery(['todos'], fetchTodos)` mounts. The query immediately returns the available cached value while the `fetchTodos` function is being run in the background to populate the query with a fresh value.
30+
- The final instance of `useQuery(['todos'], fetchTodos)` unmounts.
31+
- No more instances of `useQuery(['todos'], fetchTodos)` appear within **5 minutes**.
3232
- This query and its data are deleted and garbage collected.

docs/src/pages/guides/default-query-function.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ If you find yourself wishing for whatever reason that you could just share the s
77

88
```js
99
// Define a default query function that will receive the query key
10-
// the queryKey is guaranteed to be an Array here
1110
const defaultQueryFn = async ({ queryKey }) => {
1211
const { data } = await axios.get(`https://jsonplaceholder.typicode.com${queryKey[0]}`);
1312
return data;
@@ -32,14 +31,14 @@ function App() {
3231

3332
// All you have to do now is pass a key!
3433
function Posts() {
35-
const { status, data, error, isFetching } = useQuery('/posts')
34+
const { status, data, error, isFetching } = useQuery(['/posts'])
3635

3736
// ...
3837
}
3938

4039
// You can even leave out the queryFn and just go straight into options
4140
function Post({ postId }) {
42-
const { status, data, error, isFetching } = useQuery(`/posts/${postId}`, {
41+
const { status, data, error, isFetching } = useQuery([`/posts/${postId}`], {
4342
enabled: !!postId,
4443
})
4544

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function Todos() {
2626
error,
2727
refetch,
2828
isFetching,
29-
} = useQuery('todos', fetchTodoList, {
29+
} = useQuery(['todos'], fetchTodoList, {
3030
enabled: false,
3131
})
3232

docs/src/pages/guides/filters.md

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,31 +14,30 @@ A query filter is an object with certain conditions to match a query with:
1414
await queryClient.cancelQueries()
1515

1616
// Remove all inactive queries that begin with `posts` in the key
17-
queryClient.removeQueries('posts', { inactive: true })
17+
queryClient.removeQueries(['posts'], { type: 'inactive' })
1818

1919
// Refetch all active queries
20-
await queryClient.refetchQueries({ active: true })
20+
await queryClient.refetchQueries({ type: 'active' })
2121

2222
// Refetch all active queries that begin with `posts` in the key
23-
await queryClient.refetchQueries('posts', { active: true })
23+
await queryClient.refetchQueries(['posts'], { type: 'active' })
2424
```
2525

2626
A query filter object supports the following properties:
2727

2828
- `exact?: boolean`
2929
- 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.
30-
- `active?: boolean`
31-
- When set to `true` it will match active queries.
32-
- When set to `false` it will match inactive queries.
33-
- `inactive?: boolean`
34-
- When set to `true` it will match inactive queries.
35-
- When set to `false` it will match active queries.
30+
- `type?: 'active' | 'inactive' | 'all'`
31+
- Defaults to `all`
32+
- When set to `active` it will match active queries.
33+
- When set to `inactive` it will match inactive queries.
3634
- `stale?: boolean`
3735
- When set to `true` it will match stale queries.
3836
- When set to `false` it will match fresh queries.
39-
- `fetching?: boolean`
40-
- When set to `true` it will match queries that are currently fetching.
41-
- When set to `false` it will match queries that are not fetching.
37+
- `fetchStatus?: FetchStatus`
38+
- When set to `fetching` it will match queries that are currently fetching.
39+
- When set to `paused` it will match queries that wanted to fetch, but have been `paused`.
40+
- When set to `idle` it will match queries that are not fetching.
4241
- `predicate?: (query: Query) => boolean`
4342
- This predicate function will be called for every single query in the cache and be expected to return truthy for queries that are `found`.
4443
- `queryKey?: QueryKey`
@@ -53,7 +52,7 @@ A mutation filter is an object with certain conditions to match a mutation with:
5352
await queryClient.isMutating()
5453

5554
// Filter mutations by mutationKey
56-
await queryClient.isMutating({ mutationKey: "post" })
55+
await queryClient.isMutating({ mutationKey: ["post"] })
5756

5857
// Filter mutations using a predicate function
5958
await queryClient.isMutating({ predicate: (mutation) => mutation.options.variables?.id === 1 })

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function Projects() {
5656
isFetching,
5757
isFetchingNextPage,
5858
status,
59-
} = useInfiniteQuery('projects', fetchProjects, {
59+
} = useInfiniteQuery(['projects'], fetchProjects, {
6060
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
6161
})
6262

@@ -100,7 +100,7 @@ When an infinite query becomes `stale` and needs to be refetched, each group is
100100
If you only want to actively refetch a subset of all pages, you can pass the `refetchPage` function to `refetch` returned from `useInfiniteQuery`.
101101

102102
```js
103-
const { refetch } = useInfiniteQuery('projects', fetchProjects, {
103+
const { refetch } = useInfiniteQuery(['projects'], fetchProjects, {
104104
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
105105
})
106106

@@ -132,7 +132,7 @@ function Projects() {
132132
isFetchingNextPage,
133133
fetchNextPage,
134134
hasNextPage,
135-
} = useInfiniteQuery('projects', fetchProjects, {
135+
} = useInfiniteQuery(['projects'], fetchProjects, {
136136
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
137137
})
138138

@@ -146,7 +146,7 @@ function Projects() {
146146
Bi-directional lists can be implemented by using the `getPreviousPageParam`, `fetchPreviousPage`, `hasPreviousPage` and `isFetchingPreviousPage` properties and functions.
147147

148148
```js
149-
useInfiniteQuery('projects', fetchProjects, {
149+
useInfiniteQuery(['projects'], fetchProjects, {
150150
getNextPageParam: (lastPage, pages) => lastPage.nextCursor,
151151
getPreviousPageParam: (firstPage, pages) => firstPage.prevCursor,
152152
})
@@ -157,7 +157,7 @@ useInfiniteQuery('projects', fetchProjects, {
157157
Sometimes you may want to show the pages in reversed order. If this is case, you can use the `select` option:
158158

159159
```js
160-
useInfiniteQuery('projects', fetchProjects, {
160+
useInfiniteQuery(['projects'], fetchProjects, {
161161
select: data => ({
162162
pages: [...data.pages].reverse(),
163163
pageParams: [...data.pageParams].reverse(),
@@ -170,7 +170,7 @@ useInfiniteQuery('projects', fetchProjects, {
170170
Manually removing first page:
171171

172172
```js
173-
queryClient.setQueryData('projects', data => ({
173+
queryClient.setQueryData(['projects'], data => ({
174174
pages: data.pages.slice(1),
175175
pageParams: data.pageParams.slice(1),
176176
}))
@@ -183,7 +183,7 @@ const newPagesArray = oldPagesArray?.pages.map((page) =>
183183
page.filter((val) => val.id !== updatedId)
184184
) ?? []
185185

186-
queryClient.setQueryData('projects', data => ({
186+
queryClient.setQueryData(['projects'], data => ({
187187
pages: newPagesArray,
188188
pageParams: data.pageParams,
189189
}))

docs/src/pages/guides/initial-query-data.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ There may be times when you already have the initial data for a query available
1919
2020
```js
2121
function Todos() {
22-
const result = useQuery('todos', () => fetch('/todos'), {
22+
const result = useQuery(['todos'], () => fetch('/todos'), {
2323
initialData: initialTodos,
2424
})
2525
}
@@ -34,7 +34,7 @@ By default, `initialData` is treated as totally fresh, as if it were just fetche
3434
```js
3535
function Todos() {
3636
// Will show initialTodos immediately, but also immediately refetch todos after mount
37-
const result = useQuery('todos', () => fetch('/todos'), {
37+
const result = useQuery(['todos'], () => fetch('/todos'), {
3838
initialData: initialTodos,
3939
})
4040
}
@@ -45,7 +45,7 @@ By default, `initialData` is treated as totally fresh, as if it were just fetche
4545
```js
4646
function Todos() {
4747
// Show initialTodos immediately, but won't refetch until another interaction event is encountered after 1000 ms
48-
const result = useQuery('todos', () => fetch('/todos'), {
48+
const result = useQuery(['todos'], () => fetch('/todos'), {
4949
initialData: initialTodos,
5050
staleTime: 1000,
5151
})
@@ -56,7 +56,7 @@ By default, `initialData` is treated as totally fresh, as if it were just fetche
5656
```js
5757
function Todos() {
5858
// Show initialTodos immediately, but won't refetch until another interaction event is encountered after 1000 ms
59-
const result = useQuery('todos', () => fetch('/todos'), {
59+
const result = useQuery(['todos'], () => fetch('/todos'), {
6060
initialData: initialTodos,
6161
staleTime: 60 * 1000 // 1 minute
6262
// This could be 10 seconds ago or 10 minutes ago
@@ -74,7 +74,7 @@ If the process for accessing a query's initial data is intensive or just not som
7474

7575
```js
7676
function Todos() {
77-
const result = useQuery('todos', () => fetch('/todos'), {
77+
const result = useQuery(['todos'], () => fetch('/todos'), {
7878
initialData: () => {
7979
return getExpensiveTodos()
8080
},
@@ -91,7 +91,7 @@ function Todo({ todoId }) {
9191
const result = useQuery(['todo', todoId], () => fetch('/todos'), {
9292
initialData: () => {
9393
// Use a todo from the 'todos' query as the initial data for this todo query
94-
return queryClient.getQueryData('todos')?.find(d => d.id === todoId)
94+
return queryClient.getQueryData(['todos'])?.find(d => d.id === todoId)
9595
},
9696
})
9797
}
@@ -105,9 +105,9 @@ Getting initial data from the cache means the source query you're using to look
105105
function Todo({ todoId }) {
106106
const result = useQuery(['todo', todoId], () => fetch(`/todos/${todoId}`), {
107107
initialData: () =>
108-
queryClient.getQueryData('todos')?.find(d => d.id === todoId),
108+
queryClient.getQueryData(['todos'])?.find(d => d.id === todoId),
109109
initialDataUpdatedAt: () =>
110-
queryClient.getQueryState('todos')?.dataUpdatedAt,
110+
queryClient.getQueryState(['todos'])?.dataUpdatedAt,
111111
})
112112
}
113113
```
@@ -121,7 +121,7 @@ function Todo({ todoId }) {
121121
const result = useQuery(['todo', todoId], () => fetch(`/todos/${todoId}`), {
122122
initialData: () => {
123123
// Get the query state
124-
const state = queryClient.getQueryState('todos')
124+
const state = queryClient.getQueryState(['todos'])
125125

126126
// If the query exists and has data that is no older than 10 seconds...
127127
if (state && Date.now() - state.dataUpdatedAt <= 10 * 1000) {

docs/src/pages/guides/invalidations-from-mutations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ const queryClient = useQueryClient()
2121
// When this mutation succeeds, invalidate any queries with the `todos` or `reminders` query key
2222
const mutation = useMutation(addTodo, {
2323
onSuccess: () => {
24-
queryClient.invalidateQueries('todos')
25-
queryClient.invalidateQueries('reminders')
24+
queryClient.invalidateQueries(['todos'])
25+
queryClient.invalidateQueries(['reminders'])
2626
},
2727
})
2828
```

0 commit comments

Comments
 (0)