Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
registry-url: https://registry.npmjs.org/
- name: Install dependencies
uses: bahmutov/npm-install@v1
- run: yarn build && yarn build:types
- run: yarn build
- run: npx semantic-release@17
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
node_modules

# builds
types
build
dist
lib
es
artifacts
.rpt2_cache
coverage
*.tgz

# misc
.DS_Store
Expand All @@ -31,5 +33,3 @@ stats-hydration.json
stats-react.json
stats.html
.vscode/settings.json

types
6 changes: 6 additions & 0 deletions core/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"internal": true,
"main": "../lib/core/index.js",
"module": "../es/core/index.js",
"types": "../types/core/index.d.ts"
}
681 changes: 310 additions & 371 deletions docs/src/pages/docs/api.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/src/pages/docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Feature/Capability Key:
| Paginated Queries | ✅ | ✅ | ✅ |
| Infinite Queries | ✅ | ✅ | ✅ |
| Lagged / "Lazy" Queries<sup>1</sup> | ✅ | 🛑 | 🛑 |
| Selectors | ✅ | 🛑 | ✅ |
| Initial Data | ✅ | ✅ | ✅ |
| Scroll Recovery | ✅ | ✅ | ✅ |
| Cache Manipulation | ✅ | ✅ | ✅ |
Expand Down
273 changes: 273 additions & 0 deletions docs/src/pages/docs/guides/migrating-to-react-query-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
---
id: migrating-to-react-query-3
title: Migrating to React Query 3
---

## V3 migration

This article explains how to migrate your application to React Query 3.

### QueryClient

The `QueryCache` has been split into a `QueryClient` and a `QueryCache`.
The `QueryCache` contains all cached queries and the `QueryClient` can be used to interact with a cache.

This has some benefits:

- Allows for different type of caches.
- Multiple clients with different configurations can use the same cache.
- Clients can be used to track queries, which can be used for shared caches on SSR.
- The client API is more focused towards general usage.
- Easier to test the individual components.

Use the `QueryClientProvider` component to connect a `QueryClient` to your application:

```js
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'

const cache = new QueryCache()
const client = new QueryClient({ cache })

function App() {
return <QueryClientProvider client={client}>...</QueryClientProvider>
}
```

### useQueryCache()

The `useQueryCache()` hook has been replaced by the `useQueryClient()` hook:

```js
import { useCallback } from 'react'
import { useQueryClient } from 'react-query'

function Todo() {
const client = useQueryClient()

const onClickButton = useCallback(() => {
client.invalidateQueries('posts')
}, [client])

return <button onClick={onClickButton}>Refetch</button>
}
```

### ReactQueryConfigProvider

The `ReactQueryConfigProvider` component has been removed. Default options for queries and mutations can now be specified in `QueryClient`:

```js
const client = new QueryClient({
cache,
defaultOptions: {
queries: {
staleTime: Infinity,
},
},
})
```

### usePaginatedQuery()

The `usePaginatedQuery()` hook has been replaced by the `keepPreviousData` option on `useQuery`:

```js
import { useQuery } from 'react-query'

function Page({ page }) {
const { data } = useQuery(['page', page], fetchPage, {
keepPreviousData: true,
})
}
```

### Query object syntax

The object syntax has been collapsed:

```js
// Old:
useQuery({
queryKey: 'posts',
queryFn: fetchPosts,
config: { staleTime: Infinity },
})

// New:
useQuery({
queryKey: 'posts',
queryFn: fetchPosts,
staleTime: Infinity,
})
```

### queryCache.prefetchQuery()

The `client.prefetchQuery()` method should now only be used for prefetching scenarios where the result is not relevant.

Use the `client.fetchQueryData()` method to get the query data or error:

```js
// Prefetch a query:
await client.prefetchQuery('posts', fetchPosts)

// Fetch a query:
try {
const data = await client.fetchQueryData('posts', fetchPosts)
} catch (error) {
// Error handling
}
```

### ReactQueryCacheProvider

The `ReactQueryCacheProvider` component has been replaced by the `QueryClientProvider` component.

### makeQueryCache()

The `makeQueryCache()` function has replaced by `new QueryCache()`.

### ReactQueryErrorResetBoundary

The `ReactQueryErrorResetBoundary` component has been renamed to `QueryErrorResetBoundary`.

### queryCache.resetErrorBoundaries()

The `queryCache.resetErrorBoundaries()` method has been replaced by the `QueryErrorResetBoundary` component.

### queryCache.getQuery()

The `queryCache.getQuery()` method has been replaced by `cache.find()`.

### queryCache.getQueries()

The `queryCache.getQueries()` method has been replaced by `cache.findAll()`.

### queryCache.isFetching

The `queryCache.isFetching` property has been replaced by `client.isFetching()`.

### QueryOptions.initialStale

The `initialStale` query option has been removed and initial data is now treated as regular data.
Which means that if `initialData` is provided, the query will refetch on mount by default.
If you do not want to refetch immediately, you can define a `staleTime`.

### QueryOptions.forceFetchOnMount

The `forceFetchOnMount` query option has been replaced by `refetchOnMount: 'always'`.

### QueryOptions.refetchOnMount

When `refetchOnMount` was set to `false` any additional components were prevented from refetching on mount.
In version 3 only the component where the option has been set will not refetch on mount.

### QueryResult.clear()

The `QueryResult.clear()` method has been renamed to `QueryResult.remove()`.

### New features

Some new features have also been added besides the API changes, performance improvements and file size reduction.

#### Selectors

The `useQuery` and `useInfiniteQuery` hooks now have a `select` option to select or transform parts of the query result.

```js
import { useQuery } from 'react-query'

function User() {
const { data } = useQuery('user', fetchUser, {
select: user => user.username,
})
return <div>Username: {data}</div>
}
```

Set the `notifyOnStatusChange` option to `false` to only re-render when the selected data changes.

#### useQueries()

The `useQueries()` hook can be used to fetch a variable number of queries:

```js
import { useQueries } from 'react-query'

function Overview() {
const results = useQueries([
{ queryKey: ['post', 1], queryFn: fetchPost },
{ queryKey: ['post', 2], queryFn: fetchPost },
])
return (
<ul>
{results.map(({ data }) => data && <li key={data.id}>{data.title})</li>)}
</ul>
)
}
```

#### client.watchQuery()

The `client.watchQuery()` method can be used to create and/or watch a query:

```js
const observer = client.watchQuery('posts')

observer.subscribe(result => {
console.log(result)
observer.unsubscribe()
})
```

#### client.watchQueries()

The `client.watchQueries()` method can be used to create and/or watch multiple queries:

```js
const observer = client.watchQueries([
{ queryKey: ['post', 1], queryFn: fetchPost },
{ queryKey: ['post', 2], queryFn: fetchPost },
])

observer.subscribe(result => {
console.log(result)
observer.unsubscribe()
})
```

## `client.setQueryDefaults`

The `client.setQueryDefaults()` method to set default options for a specific query. If the query does not exist yet it will create it.

```js
client.setQueryDefaults('posts', fetchPosts)

function Component() {
const { data } = useQuery('posts')
}
```

#### React Native error screens

To prevent showing error screens in React Native when a query fails it was necessary to manually change the Console:

```js
import { setConsole } from 'react-query'

setConsole({
log: console.log,
warn: console.warn,
error: console.warn,
})
```

In version 3 this is done automatically when React Query is used in React Native.

#### Core separation

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:

```js
import { QueryClient } from 'react-query/core'
```
30 changes: 30 additions & 0 deletions docs/src/pages/docs/guides/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,3 +257,33 @@ function GlobalLoadingIndicator() {
) : null
}
```

# Query Filters

Some methods within React Query accept a `QueryFilters` object. A query filter is an object with certain conditions to match a query with:

```js
await client.refetchQueries({ active: true, inactive: true })
await client.refetchQueries('posts', { active: true, inactive: true })
```

A query filter object supports the following properties:

- `exact?: boolean`
- 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.
- `active?: boolean`
- When set to `true` it will match active queries.
- When set to `false` it will match inactive queries.
- `inactive?: boolean`
- When set to `true` it will match active queries.
- When set to `false` it will match inactive queries.
- `stale?: boolean`
- When set to `true` it will match stale queries.
- When set to `false` it will not match stale queries.
- `fresh?: boolean`
- When set to `true` it will match fresh queries.
- When set to `false` it will not match fresh queries.
- `predicate?: (query: Query) => boolean`
- This predicate function will be called for every single query in the cache and be expected to return truthy for queries that are `found`.
- `queryKey?: QueryKey`
- Set this property to define a query key to match on.
14 changes: 7 additions & 7 deletions docs/src/pages/docs/guides/suspense.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,16 @@ In addition to queries behaving differently in suspense mode, mutations also beh

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.

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

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

```js
import { ReactQueryErrorResetBoundary } from 'react-query'
import { QueryErrorResetBoundary } from 'react-query'
import { ErrorBoundary } from 'react-error-boundary'

const App: React.FC = () => (
<ReactQueryErrorResetBoundary>
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary
onReset={reset}
Expand All @@ -70,18 +70,18 @@ const App: React.FC = () => (
<Page />
</ErrorBoundary>
)}
</ReactQueryErrorResetBoundary>
</QueryErrorResetBoundary>
)
```

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:
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:

```js
import { useErrorResetBoundary } from 'react-query'
import { useQueryErrorResetBoundary } from 'react-query'
import { ErrorBoundary } from 'react-error-boundary'

const App: React.FC = () => {
const { reset } = useErrorResetBoundary()
const { reset } = useQueryErrorResetBoundary()
return (
<ErrorBoundary
onReset={reset}
Expand Down
Loading