@tanstack/react-query 4.24.10 → 5.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/build/lib/HydrationBoundary.d.ts +9 -0
  2. package/build/lib/{Hydrate.esm.js → HydrationBoundary.esm.js} +14 -17
  3. package/build/lib/HydrationBoundary.esm.js.map +1 -0
  4. package/build/lib/{Hydrate.js → HydrationBoundary.js} +17 -24
  5. package/build/lib/HydrationBoundary.js.map +1 -0
  6. package/build/lib/{Hydrate.mjs → HydrationBoundary.mjs} +14 -17
  7. package/build/lib/HydrationBoundary.mjs.map +1 -0
  8. package/build/lib/QueryClientProvider.d.ts +4 -19
  9. package/build/lib/QueryClientProvider.esm.js +11 -46
  10. package/build/lib/QueryClientProvider.esm.js.map +1 -1
  11. package/build/lib/QueryClientProvider.js +14 -52
  12. package/build/lib/QueryClientProvider.js.map +1 -1
  13. package/build/lib/QueryClientProvider.mjs +11 -46
  14. package/build/lib/QueryClientProvider.mjs.map +1 -1
  15. package/build/lib/QueryErrorResetBoundary.esm.js +7 -2
  16. package/build/lib/QueryErrorResetBoundary.esm.js.map +1 -1
  17. package/build/lib/QueryErrorResetBoundary.js +10 -8
  18. package/build/lib/QueryErrorResetBoundary.js.map +1 -1
  19. package/build/lib/QueryErrorResetBoundary.mjs +7 -2
  20. package/build/lib/QueryErrorResetBoundary.mjs.map +1 -1
  21. package/build/lib/__tests__/useQuery.types.test.d.ts +1 -2
  22. package/build/lib/__tests__/utils.d.ts +7 -10
  23. package/build/lib/errorBoundaryUtils.d.ts +3 -3
  24. package/build/lib/errorBoundaryUtils.esm.js +3 -3
  25. package/build/lib/errorBoundaryUtils.esm.js.map +1 -1
  26. package/build/lib/errorBoundaryUtils.js +6 -9
  27. package/build/lib/errorBoundaryUtils.js.map +1 -1
  28. package/build/lib/errorBoundaryUtils.mjs +3 -3
  29. package/build/lib/errorBoundaryUtils.mjs.map +1 -1
  30. package/build/lib/index.d.ts +4 -5
  31. package/build/lib/index.esm.js +3 -4
  32. package/build/lib/index.esm.js.map +1 -1
  33. package/build/lib/index.js +6 -9
  34. package/build/lib/index.js.map +1 -1
  35. package/build/lib/index.mjs +3 -4
  36. package/build/lib/index.mjs.map +1 -1
  37. package/build/lib/isRestoring.esm.js.map +1 -1
  38. package/build/lib/isRestoring.js +3 -6
  39. package/build/lib/isRestoring.js.map +1 -1
  40. package/build/lib/isRestoring.mjs.map +1 -1
  41. package/build/lib/suspense.esm.js +5 -5
  42. package/build/lib/suspense.esm.js.map +1 -1
  43. package/build/lib/suspense.js +5 -7
  44. package/build/lib/suspense.js.map +1 -1
  45. package/build/lib/suspense.mjs +5 -5
  46. package/build/lib/suspense.mjs.map +1 -1
  47. package/build/lib/types.d.ts +14 -22
  48. package/build/lib/useBaseQuery.d.ts +2 -2
  49. package/build/lib/useBaseQuery.esm.js +15 -18
  50. package/build/lib/useBaseQuery.esm.js.map +1 -1
  51. package/build/lib/useBaseQuery.js +18 -24
  52. package/build/lib/useBaseQuery.js.map +1 -1
  53. package/build/lib/useBaseQuery.mjs +15 -18
  54. package/build/lib/useBaseQuery.mjs.map +1 -1
  55. package/build/lib/useInfiniteQuery.d.ts +2 -4
  56. package/build/lib/useInfiniteQuery.esm.js +6 -4
  57. package/build/lib/useInfiniteQuery.esm.js.map +1 -1
  58. package/build/lib/useInfiniteQuery.js +5 -5
  59. package/build/lib/useInfiniteQuery.js.map +1 -1
  60. package/build/lib/useInfiniteQuery.mjs +6 -4
  61. package/build/lib/useInfiniteQuery.mjs.map +1 -1
  62. package/build/lib/useIsFetching.d.ts +2 -7
  63. package/build/lib/useIsFetching.esm.js +5 -9
  64. package/build/lib/useIsFetching.esm.js.map +1 -1
  65. package/build/lib/useIsFetching.js +7 -14
  66. package/build/lib/useIsFetching.js.map +1 -1
  67. package/build/lib/useIsFetching.mjs +5 -9
  68. package/build/lib/useIsFetching.mjs.map +1 -1
  69. package/build/lib/useMutation.d.ts +2 -5
  70. package/build/lib/useMutation.esm.js +12 -14
  71. package/build/lib/useMutation.esm.js.map +1 -1
  72. package/build/lib/useMutation.js +14 -19
  73. package/build/lib/useMutation.js.map +1 -1
  74. package/build/lib/useMutation.mjs +12 -14
  75. package/build/lib/useMutation.mjs.map +1 -1
  76. package/build/lib/useMutationState.d.ts +8 -0
  77. package/build/lib/useMutationState.esm.js +37 -0
  78. package/build/lib/useMutationState.esm.js.map +1 -0
  79. package/build/lib/useMutationState.js +59 -0
  80. package/build/lib/useMutationState.js.map +1 -0
  81. package/build/lib/useMutationState.mjs +37 -0
  82. package/build/lib/useMutationState.mjs.map +1 -0
  83. package/build/lib/useQueries.d.ts +9 -7
  84. package/build/lib/useQueries.esm.js +16 -27
  85. package/build/lib/useQueries.esm.js.map +1 -1
  86. package/build/lib/useQueries.js +19 -33
  87. package/build/lib/useQueries.js.map +1 -1
  88. package/build/lib/useQueries.mjs +16 -27
  89. package/build/lib/useQueries.mjs.map +1 -1
  90. package/build/lib/useQuery.d.ts +9 -21
  91. package/build/lib/useQuery.esm.js +5 -4
  92. package/build/lib/useQuery.esm.js.map +1 -1
  93. package/build/lib/useQuery.js +4 -5
  94. package/build/lib/useQuery.js.map +1 -1
  95. package/build/lib/useQuery.mjs +5 -4
  96. package/build/lib/useQuery.mjs.map +1 -1
  97. package/build/lib/utils.d.ts +1 -1
  98. package/build/lib/utils.esm.js +5 -6
  99. package/build/lib/utils.esm.js.map +1 -1
  100. package/build/lib/utils.js +5 -8
  101. package/build/lib/utils.js.map +1 -1
  102. package/build/lib/utils.mjs +5 -6
  103. package/build/lib/utils.mjs.map +1 -1
  104. package/build/umd/index.development.js +1003 -1827
  105. package/build/umd/index.development.js.map +1 -1
  106. package/build/umd/index.production.js +1 -1
  107. package/build/umd/index.production.js.map +1 -1
  108. package/package.json +6 -18
  109. package/src/{Hydrate.tsx → HydrationBoundary.tsx} +17 -18
  110. package/src/QueryClientProvider.tsx +11 -65
  111. package/src/__tests__/{Hydrate.test.tsx → HydrationBoundary.test.tsx} +89 -77
  112. package/src/__tests__/QueryClientProvider.test.tsx +33 -147
  113. package/src/__tests__/QueryResetErrorBoundary.test.tsx +118 -85
  114. package/src/__tests__/ssr-hydration.test.tsx +27 -33
  115. package/src/__tests__/ssr.test.tsx +23 -9
  116. package/src/__tests__/suspense.test.tsx +194 -171
  117. package/src/__tests__/useInfiniteQuery.test.tsx +249 -494
  118. package/src/__tests__/useInfiniteQuery.type.test.tsx +131 -0
  119. package/src/__tests__/useIsFetching.test.tsx +65 -108
  120. package/src/__tests__/useMutation.test.tsx +200 -268
  121. package/src/__tests__/useMutationState.test.tsx +284 -0
  122. package/src/__tests__/useQueries.test.tsx +43 -347
  123. package/src/__tests__/useQuery.test.tsx +890 -686
  124. package/src/__tests__/useQuery.types.test.tsx +23 -24
  125. package/src/__tests__/utils.tsx +14 -23
  126. package/src/errorBoundaryUtils.ts +5 -10
  127. package/src/index.ts +4 -7
  128. package/src/types.ts +33 -38
  129. package/src/useBaseQuery.ts +7 -7
  130. package/src/useInfiniteQuery.ts +13 -77
  131. package/src/useIsFetching.ts +8 -20
  132. package/src/useMutation.ts +8 -66
  133. package/src/useMutationState.ts +81 -0
  134. package/src/useQueries.ts +29 -21
  135. package/src/useQuery.ts +27 -104
  136. package/src/utils.ts +5 -5
  137. package/build/lib/Hydrate.d.ts +0 -10
  138. package/build/lib/Hydrate.esm.js.map +0 -1
  139. package/build/lib/Hydrate.js.map +0 -1
  140. package/build/lib/Hydrate.mjs.map +0 -1
  141. package/build/lib/reactBatchedUpdates.d.ts +0 -2
  142. package/build/lib/reactBatchedUpdates.esm.js +0 -6
  143. package/build/lib/reactBatchedUpdates.esm.js.map +0 -1
  144. package/build/lib/reactBatchedUpdates.js +0 -30
  145. package/build/lib/reactBatchedUpdates.js.map +0 -1
  146. package/build/lib/reactBatchedUpdates.mjs +0 -6
  147. package/build/lib/reactBatchedUpdates.mjs.map +0 -1
  148. package/build/lib/reactBatchedUpdates.native.d.ts +0 -2
  149. package/build/lib/reactBatchedUpdates.native.esm.js +0 -2
  150. package/build/lib/reactBatchedUpdates.native.esm.js.map +0 -1
  151. package/build/lib/reactBatchedUpdates.native.js +0 -13
  152. package/build/lib/reactBatchedUpdates.native.js.map +0 -1
  153. package/build/lib/reactBatchedUpdates.native.mjs +0 -2
  154. package/build/lib/reactBatchedUpdates.native.mjs.map +0 -1
  155. package/build/lib/setBatchUpdatesFn.esm.js +0 -5
  156. package/build/lib/setBatchUpdatesFn.esm.js.map +0 -1
  157. package/build/lib/setBatchUpdatesFn.js +0 -7
  158. package/build/lib/setBatchUpdatesFn.js.map +0 -1
  159. package/build/lib/setBatchUpdatesFn.mjs +0 -5
  160. package/build/lib/setBatchUpdatesFn.mjs.map +0 -1
  161. package/build/lib/useIsMutating.d.ts +0 -7
  162. package/build/lib/useIsMutating.esm.js +0 -16
  163. package/build/lib/useIsMutating.esm.js.map +0 -1
  164. package/build/lib/useIsMutating.js +0 -40
  165. package/build/lib/useIsMutating.js.map +0 -1
  166. package/build/lib/useIsMutating.mjs +0 -16
  167. package/build/lib/useIsMutating.mjs.map +0 -1
  168. package/build/lib/useSyncExternalStore.d.ts +0 -2
  169. package/build/lib/useSyncExternalStore.esm.js +0 -7
  170. package/build/lib/useSyncExternalStore.esm.js.map +0 -1
  171. package/build/lib/useSyncExternalStore.js +0 -11
  172. package/build/lib/useSyncExternalStore.js.map +0 -1
  173. package/build/lib/useSyncExternalStore.mjs +0 -7
  174. package/build/lib/useSyncExternalStore.mjs.map +0 -1
  175. package/build/lib/useSyncExternalStore.native.d.ts +0 -2
  176. package/build/lib/useSyncExternalStore.native.esm.js +0 -2
  177. package/build/lib/useSyncExternalStore.native.esm.js.map +0 -1
  178. package/build/lib/useSyncExternalStore.native.js +0 -13
  179. package/build/lib/useSyncExternalStore.native.js.map +0 -1
  180. package/build/lib/useSyncExternalStore.native.mjs +0 -2
  181. package/build/lib/useSyncExternalStore.native.mjs.map +0 -1
  182. package/codemods/v4/key-transformation.js +0 -138
  183. package/codemods/v4/replace-import-specifier.js +0 -25
  184. package/codemods/v4/utils/index.js +0 -166
  185. package/codemods/v4/utils/replacers/key-replacer.js +0 -160
  186. package/codemods/v4/utils/transformers/query-cache-transformer.js +0 -115
  187. package/codemods/v4/utils/transformers/query-client-transformer.js +0 -49
  188. package/codemods/v4/utils/transformers/use-query-like-transformer.js +0 -32
  189. package/codemods/v4/utils/unprocessable-key-error.js +0 -8
  190. package/src/__tests__/useIsMutating.test.tsx +0 -259
  191. package/src/reactBatchedUpdates.native.ts +0 -4
  192. package/src/reactBatchedUpdates.ts +0 -2
  193. package/src/setBatchUpdatesFn.ts +0 -4
  194. package/src/useIsMutating.ts +0 -39
  195. package/src/useSyncExternalStore.native.ts +0 -5
  196. package/src/useSyncExternalStore.ts +0 -4
  197. /package/build/lib/__tests__/{Hydrate.test.d.ts → HydrationBoundary.test.d.ts} +0 -0
  198. /package/build/lib/__tests__/{useIsMutating.test.d.ts → useInfiniteQuery.type.test.d.ts} +0 -0
  199. /package/build/lib/{setBatchUpdatesFn.d.ts → __tests__/useMutationState.test.d.ts} +0 -0
@@ -1,9 +1,8 @@
1
- import { fireEvent, waitFor } from '@testing-library/react'
1
+ import { fireEvent, render, waitFor } from '@testing-library/react'
2
2
  import '@testing-library/jest-dom'
3
3
  import * as React from 'react'
4
4
  import { ErrorBoundary } from 'react-error-boundary'
5
5
 
6
- import type { QueryClient } from '..'
7
6
  import { MutationCache, QueryCache, useMutation } from '..'
8
7
  import type { UseMutationResult } from '../types'
9
8
  import {
@@ -26,7 +25,7 @@ describe('useMutation', () => {
26
25
  mutate,
27
26
  data = 'empty',
28
27
  reset,
29
- } = useMutation(() => Promise.resolve('mutation'))
28
+ } = useMutation({ mutationFn: () => Promise.resolve('mutation') })
30
29
 
31
30
  return (
32
31
  <div>
@@ -56,10 +55,12 @@ describe('useMutation', () => {
56
55
 
57
56
  it('should be able to reset `error`', async () => {
58
57
  function Page() {
59
- const { mutate, error, reset } = useMutation<string, Error>(() => {
60
- const err = new Error('Expected mock error. All is well!')
61
- err.stack = ''
62
- return Promise.reject(err)
58
+ const { mutate, error, reset } = useMutation<string, Error>({
59
+ mutationFn: () => {
60
+ const err = new Error('Expected mock error. All is well!')
61
+ err.stack = ''
62
+ return Promise.reject(err)
63
+ },
63
64
  })
64
65
 
65
66
  return (
@@ -98,17 +99,16 @@ describe('useMutation', () => {
98
99
  const onSettledMock = jest.fn()
99
100
 
100
101
  function Page() {
101
- const { mutate } = useMutation(
102
- (vars: { count: number }) => Promise.resolve(vars.count),
103
- {
104
- onSuccess: (data) => {
105
- onSuccessMock(data)
106
- },
107
- onSettled: (data) => {
108
- onSettledMock(data)
109
- },
102
+ const { mutate } = useMutation({
103
+ mutationFn: (vars: { count: number }) => Promise.resolve(vars.count),
104
+
105
+ onSuccess: (data) => {
106
+ onSuccessMock(data)
110
107
  },
111
- )
108
+ onSettled: (data) => {
109
+ onSettledMock(data)
110
+ },
111
+ })
112
112
 
113
113
  return (
114
114
  <div>
@@ -154,7 +154,7 @@ describe('useMutation', () => {
154
154
  const mutateFn = jest.fn<Promise<Value>, [value: Value]>()
155
155
 
156
156
  mutateFn.mockImplementationOnce(() => {
157
- return Promise.reject('Error test Jonas')
157
+ return Promise.reject(new Error('Error test Jonas'))
158
158
  })
159
159
 
160
160
  mutateFn.mockImplementation(async (value) => {
@@ -163,18 +163,16 @@ describe('useMutation', () => {
163
163
  })
164
164
 
165
165
  function Page() {
166
- const { mutate, failureCount, failureReason, data, status } = useMutation<
167
- Value,
168
- string,
169
- Value
170
- >(mutateFn)
166
+ const { mutate, failureCount, failureReason, data, status } = useMutation(
167
+ { mutationFn: mutateFn },
168
+ )
171
169
 
172
170
  return (
173
171
  <div>
174
172
  <h1>Data {data?.count}</h1>
175
173
  <h2>Status {status}</h2>
176
174
  <h2>Failed {failureCount} times</h2>
177
- <h2>Failed because {failureReason ?? 'null'}</h2>
175
+ <h2>Failed because {failureReason?.message ?? 'null'}</h2>
178
176
  <button onClick={() => mutate({ count: ++count })}>mutate</button>
179
177
  </div>
180
178
  )
@@ -191,7 +189,7 @@ describe('useMutation', () => {
191
189
  await waitFor(() => rendered.getByText('Failed because Error test Jonas'))
192
190
 
193
191
  fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
194
- await waitFor(() => rendered.getByText('Status loading'))
192
+ await waitFor(() => rendered.getByText('Status pending'))
195
193
  await waitFor(() => rendered.getByText('Status success'))
196
194
  await waitFor(() => rendered.getByText('Data 2'))
197
195
  await waitFor(() => rendered.getByText('Failed 0 times'))
@@ -204,23 +202,21 @@ describe('useMutation', () => {
204
202
  let count = 0
205
203
 
206
204
  function Page() {
207
- const { mutate } = useMutation(
208
- (vars: { count: number }) => {
205
+ const { mutate } = useMutation({
206
+ mutationFn: (vars: { count: number }) => {
209
207
  const error = new Error(
210
208
  `Expected mock error. All is well! ${vars.count}`,
211
209
  )
212
210
  error.stack = ''
213
211
  return Promise.reject(error)
214
212
  },
215
- {
216
- onError: (error: Error) => {
217
- onErrorMock(error.message)
218
- },
219
- onSettled: (_data, error) => {
220
- onSettledMock(error?.message)
221
- },
213
+ onError: (error: Error) => {
214
+ onErrorMock(error.message)
222
215
  },
223
- )
216
+ onSettled: (_data, error) => {
217
+ onSettledMock(error?.message)
218
+ },
219
+ })
224
220
 
225
221
  return (
226
222
  <div>
@@ -273,7 +269,8 @@ describe('useMutation', () => {
273
269
  const callbacks: string[] = []
274
270
 
275
271
  function Page() {
276
- const { mutateAsync } = useMutation(async (text: string) => text, {
272
+ const { mutateAsync } = useMutation({
273
+ mutationFn: async (text: string) => text,
277
274
  onSuccess: async () => {
278
275
  callbacks.push('useMutation.onSuccess')
279
276
  },
@@ -318,17 +315,15 @@ describe('useMutation', () => {
318
315
  const callbacks: string[] = []
319
316
 
320
317
  function Page() {
321
- const { mutateAsync } = useMutation(
322
- async (_text: string) => Promise.reject('oops'),
323
- {
324
- onError: async () => {
325
- callbacks.push('useMutation.onError')
326
- },
327
- onSettled: async () => {
328
- callbacks.push('useMutation.onSettled')
329
- },
318
+ const { mutateAsync } = useMutation({
319
+ mutationFn: async (_text: string) => Promise.reject(new Error('oops')),
320
+ onError: async () => {
321
+ callbacks.push('useMutation.onError')
330
322
  },
331
- )
323
+ onSettled: async () => {
324
+ callbacks.push('useMutation.onSettled')
325
+ },
326
+ })
332
327
 
333
328
  React.useEffect(() => {
334
329
  setActTimeout(async () => {
@@ -342,7 +337,7 @@ describe('useMutation', () => {
342
337
  },
343
338
  })
344
339
  } catch (error) {
345
- callbacks.push(`mutateAsync.error:${error}`)
340
+ callbacks.push(`mutateAsync.error:${(error as Error).message}`)
346
341
  }
347
342
  }, 10)
348
343
  }, [mutateAsync])
@@ -376,7 +371,7 @@ describe('useMutation', () => {
376
371
  const states: UseMutationResult<any, any, any, any>[] = []
377
372
 
378
373
  function Page() {
379
- const state = useMutation<string, unknown, string>(key)
374
+ const state = useMutation<string, unknown, string>({ mutationKey: key })
380
375
 
381
376
  states.push(state)
382
377
 
@@ -396,25 +391,23 @@ describe('useMutation', () => {
396
391
  await sleep(100)
397
392
 
398
393
  expect(states.length).toBe(3)
399
- expect(states[0]).toMatchObject({ data: undefined, isLoading: false })
400
- expect(states[1]).toMatchObject({ data: undefined, isLoading: true })
401
- expect(states[2]).toMatchObject({ data: 'todo', isLoading: false })
394
+ expect(states[0]).toMatchObject({ data: undefined, isPending: false })
395
+ expect(states[1]).toMatchObject({ data: undefined, isPending: true })
396
+ expect(states[2]).toMatchObject({ data: 'todo', isPending: false })
402
397
  })
403
398
 
404
399
  it('should be able to retry a failed mutation', async () => {
405
400
  let count = 0
406
401
 
407
402
  function Page() {
408
- const { mutate } = useMutation(
409
- (_text: string) => {
403
+ const { mutate } = useMutation({
404
+ mutationFn: (_text: string) => {
410
405
  count++
411
- return Promise.reject('oops')
412
- },
413
- {
414
- retry: 1,
415
- retryDelay: 5,
406
+ return Promise.reject(new Error('oops'))
416
407
  },
417
- )
408
+ retry: 1,
409
+ retryDelay: 5,
410
+ })
418
411
 
419
412
  React.useEffect(() => {
420
413
  setActTimeout(() => {
@@ -438,16 +431,14 @@ describe('useMutation', () => {
438
431
  let count = 0
439
432
 
440
433
  function Page() {
441
- const mutation = useMutation(
442
- (_text: string) => {
434
+ const mutation = useMutation({
435
+ mutationFn: (_text: string) => {
443
436
  count++
444
437
  return Promise.reject(new Error('oops'))
445
438
  },
446
- {
447
- retry: 1,
448
- retryDelay: 5,
449
- },
450
- )
439
+ retry: 1,
440
+ retryDelay: 5,
441
+ })
451
442
 
452
443
  return (
453
444
  <div>
@@ -473,7 +464,7 @@ describe('useMutation', () => {
473
464
 
474
465
  await waitFor(() => {
475
466
  expect(
476
- rendered.getByText('error: null, status: loading, isPaused: true'),
467
+ rendered.getByText('error: null, status: pending, isPaused: true'),
477
468
  ).toBeInTheDocument()
478
469
  })
479
470
 
@@ -501,16 +492,14 @@ describe('useMutation', () => {
501
492
  let count = 0
502
493
 
503
494
  function Page() {
504
- const mutation = useMutation(
505
- async (_text: string) => {
495
+ const mutation = useMutation({
496
+ mutationFn: async (_text: string) => {
506
497
  count++
507
498
  await sleep(10)
508
499
  return count
509
500
  },
510
- {
511
- onMutate,
512
- },
513
- )
501
+ onMutate,
502
+ })
514
503
 
515
504
  return (
516
505
  <div>
@@ -529,7 +518,7 @@ describe('useMutation', () => {
529
518
 
530
519
  fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
531
520
 
532
- await rendered.findByText('data: null, status: loading, isPaused: true')
521
+ await rendered.findByText('data: null, status: pending, isPaused: true')
533
522
 
534
523
  expect(onMutate).toHaveBeenCalledTimes(1)
535
524
  expect(onMutate).toHaveBeenCalledWith('todo')
@@ -551,10 +540,12 @@ describe('useMutation', () => {
551
540
  const states: Array<string> = []
552
541
 
553
542
  function Page() {
554
- const mutation = useMutation(async (_text: string) => {
555
- count++
556
- await sleep(10)
557
- return count
543
+ const mutation = useMutation({
544
+ mutationFn: async (_text: string) => {
545
+ count++
546
+ await sleep(10)
547
+ return count
548
+ },
558
549
  })
559
550
 
560
551
  states.push(`${mutation.status}, ${mutation.isPaused}`)
@@ -576,11 +567,11 @@ describe('useMutation', () => {
576
567
 
577
568
  fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
578
569
 
579
- await rendered.findByText('data: null, status: loading, isPaused: true')
570
+ await rendered.findByText('data: null, status: pending, isPaused: true')
580
571
 
581
- // no intermediate 'loading, false' state is expected because we don't start mutating!
572
+ // no intermediate 'pending, false' state is expected because we don't start mutating!
582
573
  expect(states[0]).toBe('idle, false')
583
- expect(states[1]).toBe('loading, true')
574
+ expect(states[1]).toBe('pending, true')
584
575
 
585
576
  onlineMock.mockReturnValue(true)
586
577
  window.dispatchEvent(new Event('online'))
@@ -597,18 +588,18 @@ describe('useMutation', () => {
597
588
  const states: UseMutationResult<any, any, any, any>[] = []
598
589
 
599
590
  function Page() {
600
- const state = useMutation(
601
- async (_text: string) => {
591
+ const state = useMutation({
592
+ mutationFn: async (_text: string) => {
602
593
  await sleep(1)
603
594
  count++
604
- return count > 1 ? Promise.resolve('data') : Promise.reject('oops')
595
+ return count > 1
596
+ ? Promise.resolve('data')
597
+ : Promise.reject(new Error('oops'))
605
598
  },
606
- {
607
- retry: 1,
608
- retryDelay: 5,
609
- networkMode: 'offlineFirst',
610
- },
611
- )
599
+ retry: 1,
600
+ retryDelay: 5,
601
+ networkMode: 'offlineFirst',
602
+ })
612
603
 
613
604
  states.push(state)
614
605
 
@@ -629,28 +620,28 @@ describe('useMutation', () => {
629
620
 
630
621
  expect(states.length).toBe(4)
631
622
  expect(states[0]).toMatchObject({
632
- isLoading: false,
623
+ isPending: false,
633
624
  isPaused: false,
634
625
  failureCount: 0,
635
626
  failureReason: null,
636
627
  })
637
628
  expect(states[1]).toMatchObject({
638
- isLoading: true,
629
+ isPending: true,
639
630
  isPaused: false,
640
631
  failureCount: 0,
641
632
  failureReason: null,
642
633
  })
643
634
  expect(states[2]).toMatchObject({
644
- isLoading: true,
635
+ isPending: true,
645
636
  isPaused: false,
646
637
  failureCount: 1,
647
- failureReason: 'oops',
638
+ failureReason: new Error('oops'),
648
639
  })
649
640
  expect(states[3]).toMatchObject({
650
- isLoading: true,
641
+ isPending: true,
651
642
  isPaused: true,
652
643
  failureCount: 1,
653
- failureReason: 'oops',
644
+ failureReason: new Error('oops'),
654
645
  })
655
646
 
656
647
  onlineMock.mockReturnValue(true)
@@ -660,13 +651,13 @@ describe('useMutation', () => {
660
651
 
661
652
  expect(states.length).toBe(6)
662
653
  expect(states[4]).toMatchObject({
663
- isLoading: true,
654
+ isPending: true,
664
655
  isPaused: false,
665
656
  failureCount: 1,
666
- failureReason: 'oops',
657
+ failureReason: new Error('oops'),
667
658
  })
668
659
  expect(states[5]).toMatchObject({
669
- isLoading: false,
660
+ isPending: false,
670
661
  isPaused: false,
671
662
  failureCount: 0,
672
663
  failureReason: null,
@@ -678,7 +669,7 @@ describe('useMutation', () => {
678
669
 
679
670
  it('should not change state if unmounted', async () => {
680
671
  function Mutates() {
681
- const { mutate } = useMutation(() => sleep(10))
672
+ const { mutate } = useMutation({ mutationFn: () => sleep(10) })
682
673
  return <button onClick={() => mutate()}>mutate</button>
683
674
  }
684
675
  function Page() {
@@ -696,16 +687,19 @@ describe('useMutation', () => {
696
687
  fireEvent.click(getByText('unmount'))
697
688
  })
698
689
 
699
- it('should be able to throw an error when useErrorBoundary is set to true', async () => {
690
+ it('should be able to throw an error when throwErrors is set to true', async () => {
691
+ const consoleMock = jest
692
+ .spyOn(console, 'error')
693
+ .mockImplementation(() => undefined)
700
694
  function Page() {
701
- const { mutate } = useMutation<string, Error>(
702
- () => {
695
+ const { mutate } = useMutation<string, Error>({
696
+ mutationFn: () => {
703
697
  const err = new Error('Expected mock error. All is well!')
704
698
  err.stack = ''
705
699
  return Promise.reject(err)
706
700
  },
707
- { useErrorBoundary: true },
708
- )
701
+ throwErrors: true,
702
+ })
709
703
 
710
704
  return (
711
705
  <div>
@@ -732,24 +726,31 @@ describe('useMutation', () => {
732
726
  await waitFor(() => {
733
727
  expect(queryByText('error')).not.toBeNull()
734
728
  })
729
+
730
+ expect(consoleMock).toHaveBeenCalledWith(
731
+ expect.objectContaining(new Error('Expected mock error. All is well!')),
732
+ )
733
+
734
+ consoleMock.mockRestore()
735
735
  })
736
736
 
737
- it('should be able to throw an error when useErrorBoundary is a function that returns true', async () => {
737
+ it('should be able to throw an error when throwErrors is a function that returns true', async () => {
738
+ const consoleMock = jest
739
+ .spyOn(console, 'error')
740
+ .mockImplementation(() => undefined)
738
741
  let boundary = false
739
742
  function Page() {
740
- const { mutate, error } = useMutation<string, Error>(
741
- () => {
743
+ const { mutate, error } = useMutation<string, Error>({
744
+ mutationFn: () => {
742
745
  const err = new Error('mock error')
743
746
  err.stack = ''
744
747
  return Promise.reject(err)
745
748
  },
746
- {
747
- useErrorBoundary: () => {
748
- boundary = !boundary
749
- return !boundary
750
- },
749
+ throwErrors: () => {
750
+ boundary = !boundary
751
+ return !boundary
751
752
  },
752
- )
753
+ })
753
754
 
754
755
  return (
755
756
  <div>
@@ -783,6 +784,7 @@ describe('useMutation', () => {
783
784
  await waitFor(() => {
784
785
  expect(queryByText('error boundary')).not.toBeNull()
785
786
  })
787
+ consoleMock.mockRestore()
786
788
  })
787
789
 
788
790
  it('should pass meta to mutation', async () => {
@@ -804,17 +806,16 @@ describe('useMutation', () => {
804
806
  const metaErrorMessage = 'mutation failed'
805
807
 
806
808
  function Page() {
807
- const { mutate: succeed, isSuccess } = useMutation(async () => '', {
809
+ const { mutate: succeed, isSuccess } = useMutation({
810
+ mutationFn: async () => '',
808
811
  meta: { metaSuccessMessage },
809
812
  })
810
- const { mutate: error, isError } = useMutation(
811
- async () => {
813
+ const { mutate: error, isError } = useMutation({
814
+ mutationFn: async () => {
812
815
  throw new Error('')
813
816
  },
814
- {
815
- meta: { metaErrorMessage },
816
- },
817
- )
817
+ meta: { metaErrorMessage },
818
+ })
818
819
 
819
820
  return (
820
821
  <div>
@@ -864,19 +865,17 @@ describe('useMutation', () => {
864
865
  }
865
866
 
866
867
  function Component() {
867
- const mutation = useMutation(
868
- async (_text: string) => {
868
+ const mutation = useMutation({
869
+ mutationFn: async (_text: string) => {
869
870
  count++
870
871
  await sleep(10)
871
872
  return count
872
873
  },
873
- {
874
- mutationKey,
875
- cacheTime: 0,
876
- onSuccess,
877
- onSettled,
878
- },
879
- )
874
+ mutationKey,
875
+ gcTime: 0,
876
+ onSuccess,
877
+ onSettled,
878
+ })
880
879
 
881
880
  return (
882
881
  <div>
@@ -919,68 +918,6 @@ describe('useMutation', () => {
919
918
  expect(onSettledMutate).toHaveBeenCalledTimes(0)
920
919
  })
921
920
 
922
- describe('with custom context', () => {
923
- it('should be able to reset `data`', async () => {
924
- const context = React.createContext<QueryClient | undefined>(undefined)
925
-
926
- function Page() {
927
- const {
928
- mutate,
929
- data = 'empty',
930
- reset,
931
- } = useMutation(() => Promise.resolve('mutation'), { context })
932
-
933
- return (
934
- <div>
935
- <h1>{data}</h1>
936
- <button onClick={() => reset()}>reset</button>
937
- <button onClick={() => mutate()}>mutate</button>
938
- </div>
939
- )
940
- }
941
-
942
- const { getByRole } = renderWithClient(queryClient, <Page />, { context })
943
-
944
- expect(getByRole('heading').textContent).toBe('empty')
945
-
946
- fireEvent.click(getByRole('button', { name: /mutate/i }))
947
-
948
- await waitFor(() => {
949
- expect(getByRole('heading').textContent).toBe('mutation')
950
- })
951
-
952
- fireEvent.click(getByRole('button', { name: /reset/i }))
953
-
954
- await waitFor(() => {
955
- expect(getByRole('heading').textContent).toBe('empty')
956
- })
957
- })
958
-
959
- it('should throw if the context is not passed to useMutation', async () => {
960
- const context = React.createContext<QueryClient | undefined>(undefined)
961
-
962
- function Page() {
963
- const { data = '' } = useMutation(() => Promise.resolve('mutation'))
964
-
965
- return (
966
- <div>
967
- <h1 data-testid="title">{data}</h1>
968
- </div>
969
- )
970
- }
971
-
972
- const rendered = renderWithClient(
973
- queryClient,
974
- <ErrorBoundary fallbackRender={() => <div>error boundary</div>}>
975
- <Page />
976
- </ErrorBoundary>,
977
- { context },
978
- )
979
-
980
- await waitFor(() => rendered.getByText('error boundary'))
981
- })
982
- })
983
-
984
921
  it('should call mutate callbacks only for the last observer', async () => {
985
922
  const onSuccess = jest.fn()
986
923
  const onSuccessMutate = jest.fn()
@@ -989,29 +926,38 @@ describe('useMutation', () => {
989
926
  let count = 0
990
927
 
991
928
  function Page() {
992
- const mutation = useMutation(
993
- async (_text: string) => {
929
+ const mutation = useMutation({
930
+ mutationFn: async (text: string) => {
994
931
  count++
932
+ const result = `result-${text}`
995
933
  await sleep(10)
996
- return `result${count}`
997
- },
998
- {
999
- onSuccess,
1000
- onSettled,
934
+ return result
1001
935
  },
1002
- )
936
+ onSuccess,
937
+ onSettled,
938
+ })
1003
939
 
1004
940
  return (
1005
941
  <div>
1006
942
  <button
1007
943
  onClick={() =>
1008
- mutation.mutate('todo', {
944
+ mutation.mutate('todo1', {
1009
945
  onSuccess: onSuccessMutate,
1010
946
  onSettled: onSettledMutate,
1011
947
  })
1012
948
  }
1013
949
  >
1014
- mutate
950
+ mutate1
951
+ </button>
952
+ <button
953
+ onClick={() =>
954
+ mutation.mutate('todo2', {
955
+ onSuccess: onSuccessMutate,
956
+ onSettled: onSettledMutate,
957
+ })
958
+ }
959
+ >
960
+ mutate2
1015
961
  </button>
1016
962
  <div>
1017
963
  data: {mutation.data ?? 'null'}, status: {mutation.status}
@@ -1024,22 +970,38 @@ describe('useMutation', () => {
1024
970
 
1025
971
  await rendered.findByText('data: null, status: idle')
1026
972
 
1027
- fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
1028
- fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
973
+ fireEvent.click(rendered.getByRole('button', { name: /mutate1/i }))
974
+ fireEvent.click(rendered.getByRole('button', { name: /mutate2/i }))
1029
975
 
1030
- await rendered.findByText('data: result2, status: success')
976
+ await rendered.findByText('data: result-todo2, status: success')
1031
977
 
1032
978
  expect(count).toBe(2)
1033
979
 
1034
980
  expect(onSuccess).toHaveBeenCalledTimes(2)
981
+ expect(onSuccess).toHaveBeenNthCalledWith(
982
+ 1,
983
+ 'result-todo1',
984
+ 'todo1',
985
+ undefined,
986
+ )
987
+ expect(onSuccess).toHaveBeenNthCalledWith(
988
+ 2,
989
+ 'result-todo2',
990
+ 'todo2',
991
+ undefined,
992
+ )
1035
993
  expect(onSettled).toHaveBeenCalledTimes(2)
1036
994
  expect(onSuccessMutate).toHaveBeenCalledTimes(1)
1037
- expect(onSuccessMutate).toHaveBeenCalledWith('result2', 'todo', undefined)
995
+ expect(onSuccessMutate).toHaveBeenCalledWith(
996
+ 'result-todo2',
997
+ 'todo2',
998
+ undefined,
999
+ )
1038
1000
  expect(onSettledMutate).toHaveBeenCalledTimes(1)
1039
1001
  expect(onSettledMutate).toHaveBeenCalledWith(
1040
- 'result2',
1002
+ 'result-todo2',
1041
1003
  null,
1042
- 'todo',
1004
+ 'todo2',
1043
1005
  undefined,
1044
1006
  )
1045
1007
  })
@@ -1049,16 +1011,14 @@ describe('useMutation', () => {
1049
1011
  const onError = jest.fn()
1050
1012
 
1051
1013
  function Page() {
1052
- const mutation = useMutation(
1053
- async (_text: string) => {
1014
+ const mutation = useMutation({
1015
+ mutationFn: async (_text: string) => {
1054
1016
  await sleep(10)
1055
1017
  return 'result'
1056
1018
  },
1057
- {
1058
- onSuccess: () => Promise.reject(error),
1059
- onError,
1060
- },
1061
- )
1019
+ onSuccess: () => Promise.reject(error),
1020
+ onError,
1021
+ })
1062
1022
 
1063
1023
  return (
1064
1024
  <div>
@@ -1084,15 +1044,13 @@ describe('useMutation', () => {
1084
1044
  const mutateFnError = new Error('mutateFnError')
1085
1045
 
1086
1046
  function Page() {
1087
- const mutation = useMutation(
1088
- async (_text: string) => {
1047
+ const mutation = useMutation({
1048
+ mutationFn: async (_text: string) => {
1089
1049
  await sleep(10)
1090
1050
  throw mutateFnError
1091
1051
  },
1092
- {
1093
- onError: () => Promise.reject(error),
1094
- },
1095
- )
1052
+ onError: () => Promise.reject(error),
1053
+ })
1096
1054
 
1097
1055
  return (
1098
1056
  <div>
@@ -1121,16 +1079,14 @@ describe('useMutation', () => {
1121
1079
  const onError = jest.fn()
1122
1080
 
1123
1081
  function Page() {
1124
- const mutation = useMutation(
1125
- async (_text: string) => {
1082
+ const mutation = useMutation({
1083
+ mutationFn: async (_text: string) => {
1126
1084
  await sleep(10)
1127
1085
  throw mutateFnError
1128
1086
  },
1129
- {
1130
- onSettled: () => Promise.reject(error),
1131
- onError,
1132
- },
1133
- )
1087
+ onSettled: () => Promise.reject(error),
1088
+ onError,
1089
+ })
1134
1090
 
1135
1091
  return (
1136
1092
  <div>
@@ -1155,59 +1111,35 @@ describe('useMutation', () => {
1155
1111
  expect(onError).toHaveBeenCalledWith(mutateFnError, 'todo', undefined)
1156
1112
  })
1157
1113
 
1158
- it('should not call mutate callbacks for mutations started after unmount', async () => {
1159
- const onSuccessMutate = jest.fn()
1160
- const onSuccessUseMutation = jest.fn()
1161
- const onSettledMutate = jest.fn()
1162
- const onSettledUseMutation = jest.fn()
1163
-
1114
+ it('should use provided custom queryClient', async () => {
1164
1115
  function Page() {
1165
- const [show, setShow] = React.useState(true)
1166
- return (
1167
- <div>
1168
- <button onClick={() => setShow(false)}>hide</button>
1169
- {show && <Component />}
1170
- </div>
1171
- )
1172
- }
1173
-
1174
- function Component() {
1175
- const mutation = useMutation({
1176
- mutationFn: async (text: string) => {
1177
- await sleep(10)
1178
- return text
1116
+ const mutation = useMutation(
1117
+ {
1118
+ mutationFn: async (text: string) => {
1119
+ return Promise.resolve(text)
1120
+ },
1179
1121
  },
1180
- onSuccess: onSuccessUseMutation,
1181
- onSettled: onSettledUseMutation,
1182
- })
1122
+ queryClient,
1123
+ )
1183
1124
 
1184
1125
  return (
1185
1126
  <div>
1186
- <button
1187
- onClick={() => {
1188
- setActTimeout(() => {
1189
- mutation.mutate('todo', {
1190
- onSuccess: onSuccessMutate,
1191
- onSettled: onSettledMutate,
1192
- })
1193
- }, 10)
1194
- }}
1195
- >
1127
+ <button onClick={() => mutation.mutate('custom client')}>
1196
1128
  mutate
1197
1129
  </button>
1130
+ <div>
1131
+ data: {mutation.data ?? 'null'}, status: {mutation.status}
1132
+ </div>
1198
1133
  </div>
1199
1134
  )
1200
1135
  }
1201
1136
 
1202
- const rendered = renderWithClient(queryClient, <Page />)
1137
+ const rendered = render(<Page></Page>)
1203
1138
 
1204
- fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
1205
- fireEvent.click(rendered.getByRole('button', { name: /hide/i }))
1139
+ await rendered.findByText('data: null, status: idle')
1206
1140
 
1207
- await waitFor(() => expect(onSuccessUseMutation).toHaveBeenCalledTimes(1))
1208
- await waitFor(() => expect(onSettledUseMutation).toHaveBeenCalledTimes(1))
1141
+ fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
1209
1142
 
1210
- expect(onSuccessMutate).toHaveBeenCalledTimes(0)
1211
- expect(onSettledMutate).toHaveBeenCalledTimes(0)
1143
+ await rendered.findByText('data: custom client, status: success')
1212
1144
  })
1213
1145
  })