Skip to content

Commit

Permalink
feat: no retries on the server (#5802)
Browse files Browse the repository at this point in the history
* feat: zero retries on the server

* test: no retry on the server

* docs: no retry on the server
  • Loading branch information
TkDodo committed Jul 29, 2023
1 parent 251fb6f commit 6fcfc9b
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
4 changes: 4 additions & 0 deletions docs/react/guides/migrating-to-v5.md
Expand Up @@ -341,6 +341,10 @@ useInfiniteQuery({

Previously, we've allowed to overwrite the `pageParams` that would be returned from `getNextPageParam` or `getPreviousPageParam` by passing a `pageParam` value directly to `fetchNextPage` or `fetchPreviousPage`. This feature didn't work at all with refetches and wasn't widely known or used. This also means that `getNextPageParam` is now required for infinite queries.

### No retries on the server

On the server, `retry` now defaults to `0` instead of `3`. For prefetching, we have always defaulted to `0` retries, but since queries that have `suspense` enabled can now execute directly on the server as well (since React18), we have to make sure that we don't retry on the server at all.

[//]: # 'FrameworkBreakingChanges'

## React Query Breaking Changes
Expand Down
2 changes: 2 additions & 0 deletions docs/react/guides/query-retries.md
Expand Up @@ -12,6 +12,8 @@ You can configure retries both on a global level and an individual query level.
- Setting `retry = true` will infinitely retry failing requests.
- Setting `retry = (failureCount, error) => ...` allows for custom logic based on why the request failed.

> On the server, retries default to `0` to make server rendering as fast as possible.
[//]: # 'Example'

```tsx
Expand Down
1 change: 1 addition & 0 deletions docs/react/reference/useQuery.md
Expand Up @@ -79,6 +79,7 @@ const {
- If `false`, failed queries will not retry by default.
- If `true`, failed queries will retry infinitely.
- If set to a `number`, e.g. `3`, failed queries will retry until the failed query count meets that number.
- defaults to `3` on the client and `0` on the server
- `retryOnMount: boolean`
- If set to `false`, the query will not be retried on mount if it contains an error. Defaults to `true`.
- `retryDelay: number | (retryAttempt: number, error: TError) => number`
Expand Down
4 changes: 2 additions & 2 deletions packages/query-core/src/retryer.ts
@@ -1,6 +1,6 @@
import { focusManager } from './focusManager'
import { onlineManager } from './onlineManager'
import { sleep } from './utils'
import { isServer, sleep } from './utils'
import type { CancelOptions, DefaultError, NetworkMode } from './types'

// TYPES
Expand Down Expand Up @@ -158,7 +158,7 @@ export function createRetryer<TData = unknown, TError = DefaultError>(
}

// Do we need to retry the request?
const retry = config.retry ?? 3
const retry = config.retry ?? (isServer ? 0 : 3)
const retryDelay = config.retryDelay ?? defaultRetryDelay
const delay =
typeof retryDelay === 'function'
Expand Down
22 changes: 22 additions & 0 deletions packages/query-core/src/tests/query.test.tsx
Expand Up @@ -5,6 +5,7 @@ import {
createQueryClient,
mockVisibilityState,
queryKey,
setIsServer,
sleep,
} from './utils'
import type {
Expand Down Expand Up @@ -804,6 +805,27 @@ describe('query', () => {
consoleMock.mockRestore()
})

it('should not retry on the server', async () => {
const resetIsServer = setIsServer(true)

const key = queryKey()
let count = 0

const observer = new QueryObserver(queryClient, {
queryKey: key,
queryFn: () => {
count++
return Promise.reject(new Error('error'))
},
})

await observer.refetch()

expect(count).toBe(1)

resetIsServer()
})

test('constructor should call initialDataUpdatedAt if defined as a function', async () => {
const key = queryKey()

Expand Down

0 comments on commit 6fcfc9b

Please sign in to comment.