Skip to content

Commit 3a8bda8

Browse files
committed
2 parents 5f806e3 + a75c285 commit 3a8bda8

File tree

8 files changed

+155
-49
lines changed

8 files changed

+155
-49
lines changed

.size-snapshot.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"dist/index.js": {
3-
"bundled": 29796,
4-
"minified": 14847,
5-
"gzipped": 4213
3+
"bundled": 29896,
4+
"minified": 14904,
5+
"gzipped": 4226
66
},
77
"dist/index.es.js": {
8-
"bundled": 29276,
9-
"minified": 14383,
10-
"gzipped": 4111,
8+
"bundled": 29376,
9+
"minified": 14440,
10+
"gzipped": 4125,
1111
"treeshaked": {
1212
"rollup": {
1313
"code": 3472,

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Tools for managing async data and client stores/caches are plentiful these days,
5353
- Force normalized or object/id-based caching strategies on your data
5454
- Do not automatically manage stale-ness or caching
5555
- Do not offer robust API's around mutation events, invalidation or query management
56-
- Are built for highly-opinionated systems like Redux, GraphQL, [insert proprietary tools] etc.
56+
- Are built for highly-opinionated systems like Redux, GraphQL, [insert proprietary tools], etc.
5757

5858
## The Solution
5959

@@ -299,7 +299,7 @@ function Todos() {
299299

300300
### Query Keys
301301

302-
Since React Query uses a query's **unique key** for essentially everything, it's important to tailor them so that will change with your query requirements. In other libraries like Zeit's SWR, you'll see the use of URL's and GraphQL query template strings to achieve this, but we believe at scale, this becomes prone to typos and errors. To relieve this issue, you can pass a **tuple key** with a `string` and `object` of variables to deterministically get the the same key.
302+
Since React Query uses a query's **unique key** for essentially everything, it's important to tailor them so that they will change with your query requirements. In other libraries like Zeit's SWR, you'll see the use of URL's and GraphQL query template strings to achieve this, but we believe at scale, this becomes prone to typos and errors. To relieve this issue, you can pass a **tuple key** with a `string` and `object` of variables to deterministically get the same key.
303303

304304
> Pro Tip: Variables passed in the key are automatically passed to your query function!
305305
@@ -313,7 +313,7 @@ useQuery(['todos', { page, status, other: undefined }])
313313

314314
### Query Variables
315315

316-
To use external props, state, or variables in a query function, pass them as a variables in your query key! They will be passed through to your query function as the first parameter.
316+
To use external props, state, or variables in a query function, pass them as a variable in your query key! They will be passed through to your query function as the first parameter.
317317

318318
```js
319319
function Todos({ status }) {
@@ -409,7 +409,7 @@ Let's assume we are using the default `cacheTime` of **5 minutes** and the defau
409409
- A second instance of `useQuery('todos', fetchTodos)` mounts elsewhere.
410410
- Because this exact data exist in the cache from the first instance of this query, that data is immediately returned from the cache.
411411
- Since the query is stale, it is refetched in the background automatically.
412-
- Both instances of the `useQuery('todos', fetchTodos)` query are unmount and no longer in use.
412+
- Both instances of the `useQuery('todos', fetchTodos)` query are unmounted and no longer in use.
413413
- Since there are no more active instances to this query, a cache timeout is set using `cacheTime` to delete and garbage collect the query (defaults to **5 minutes**).
414414
- No more instances of `useQuery('todos', fetchTodos)` appear within **5 minutes**.
415415
- This query and its data is deleted and garbage collected.
@@ -661,7 +661,7 @@ const { data, isLoading, error } = useQuery('todos', fetchTodoList, {
661661
// data === [{ id: 0, name: 'Implement SSR!'}]
662662
```
663663
664-
The query's state will still reflect that it is stale and has not been fetched yet, and once mounted, will continue as normal and request a fresh copy of the query result.
664+
The query's state will still reflect that it is stale and has not been fetched yet, and once mounted, it will continue as normal and request a fresh copy of the query result.
665665
666666
### Suspense Mode
667667
@@ -944,7 +944,7 @@ setQueryData(['todo', { id: 5 }], newTodo)
944944
setQueryData(['todo', { id: 5 }], previous => ({ ...previous, status: 'done' }))
945945
```
946946
947-
**Most importantly**, when manually setting a query response, it naturally becomes out-of-sync with it's original source. To ease this issue, `setQueryData` automatically triggers a background refresh of the query after it's called to ensure it eventually synchronizes with the original source.
947+
**Most importantly**, when manually setting a query response, it naturally becomes out-of-sync with its original source. To ease this issue, `setQueryData` automatically triggers a background refresh of the query after it's called to ensure it eventually synchronizes with the original source.
948948
949949
Should you choose that you do _not_ want to refetch the query automatically, you can set the `shouldRefetch` option to `false`:
950950
@@ -1015,7 +1015,7 @@ function App() {
10151015
10161016
### Custom Window Focus Event
10171017
1018-
In rare circumstances, you may want manage your own window focus events that trigger React Query to revalidate. To do this, React Query provides a `setFocusHandler` function that supplies you the callback that should be fired when the window is focused and allows you to set up your own events. When calling `setFocusHandler`, the previously set handler is removed (which in most cases will be the defalt handler) and your new handler is used instead. For example, this is the default handler:
1018+
In rare circumstances, you may want to manage your own window focus events that trigger React Query to revalidate. To do this, React Query provides a `setFocusHandler` function that supplies you the callback that should be fired when the window is focused and allows you to set up your own events. When calling `setFocusHandler`, the previously set handler is removed (which in most cases will be the default handler) and your new handler is used instead. For example, this is the default handler:
10191019
10201020
```js
10211021
setFocusHandler(handleFocus => {
@@ -1035,7 +1035,7 @@ setFocusHandler(handleFocus => {
10351035
10361036
### Ignoring Iframe Focus Events
10371037
1038-
A greate use-case for replacing the focus handler is that of iframe events. Iframes present problems with detecting window focus by both double-firing events and also firing false-positive events when focusing or using iframes within your app. If you experience this, you should use an event handler that ignores these events as much as possible. I recommend [this one](https://gist.github.com/tannerlinsley/1d3a2122332107fcd8c9cc379be10d88)! It can be set up in the following way:
1038+
A great use-case for replacing the focus handler is that of iframe events. Iframes present problems with detecting window focus by both double-firing events and also firing false-positive events when focusing or using iframes within your app. If you experience this, you should use an event handler that ignores these events as much as possible. I recommend [this one](https://gist.github.com/tannerlinsley/1d3a2122332107fcd8c9cc379be10d88)! It can be set up in the following way:
10391039
10401040
```js
10411041
import { setFocusHandler } from 'react-query'
@@ -1439,7 +1439,7 @@ const maybePromise = setQueryData(queryKey, data, { shouldRefetch })
14391439
### Returns
14401440
14411441
- `maybePromise: undefined | Promise`
1442-
- If `shouldRefetch` is `true`, a promise is returned that will either resolve when the query refetch is complete or will reject if the refetch fails (after its respective retry configurations is done).
1442+
- If `shouldRefetch` is `true`, a promise is returned that will either resolve when the query refetch is complete or will reject if the refetch fails (after its respective retry configurations are done).
14431443
14441444
## `refetchQuery`
14451445
@@ -1491,7 +1491,7 @@ const promise = refetchAllQueries({ force, includeInactive })
14911491
- `includeInactive: Boolean`
14921492
- Optional
14931493
- Set this to `true` to also refetch inactive queries.
1494-
- Overrides the `force` option to be `true`, regardless of it's value.
1494+
- Overrides the `force` option to be `true`, regardless of its value.
14951495
14961496
### Returns
14971497

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"@babel/preset-env": "^7.4.5",
3131
"@babel/preset-react": "^7.0.0",
3232
"@svgr/rollup": "^4.3.0",
33+
"@testing-library/react": "^9.4.0",
3334
"babel-core": "7.0.0-bridge.0",
3435
"babel-eslint": "9.x",
3536
"babel-jest": "^24.9.0",

sizes-cjs.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[
22
{
3-
"timestamp": 1579297800315,
3+
"timestamp": 1581914470302,
44
"files": [
55
{
66
"filename": "index.js",
7-
"size": 6873,
8-
"delta": -4
7+
"size": 6890,
8+
"delta": 17
99
}
1010
]
1111
}

sizes-es.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
[
22
{
3-
"timestamp": 1579297807616,
3+
"timestamp": 1581914475725,
44
"files": [
55
{
66
"filename": "index.es.js",
7-
"size": 6736,
8-
"delta": -3
7+
"size": 6752,
8+
"delta": 16
99
}
1010
]
1111
}

src/__tests__/useMutation-test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
cleanup,
3+
render,
4+
fireEvent,
5+
} from '@testing-library/react'
6+
import * as React from 'react'
7+
import { act } from 'react-dom/test-utils'
8+
9+
import { useMutation } from '../index'
10+
11+
describe('useMutation', () => {
12+
afterEach(cleanup)
13+
14+
it('should be able to reset `data`', async () => {
15+
function Page() {
16+
const [mutate, mutationResult] = useMutation(() => Promise.resolve('mutation'))
17+
18+
return (
19+
<div>
20+
<h1 data-testid="title">{mutationResult.data}</h1>
21+
<button onClick={mutationResult.reset}>reset</button>
22+
<button onClick={mutate}>mutate</button>
23+
</div>
24+
)
25+
}
26+
27+
const { getByTestId, getByText } = render(<Page />)
28+
29+
expect(getByTestId('title').textContent).toBe('')
30+
31+
await act(async () => {
32+
fireEvent.click(getByText('mutate'))
33+
})
34+
35+
expect(getByTestId('title').textContent).toBe('mutation')
36+
37+
await act(async () => {
38+
fireEvent.click(getByText('reset'))
39+
})
40+
41+
expect(getByTestId('title').textContent).toBe('')
42+
})
43+
})

src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,9 @@ export function useMutation(
668668
[refetchQueriesOnFailure, refetchQueries]
669669
)
670670

671-
return [mutate, { data, isLoading, error }]
671+
const reset = React.useCallback(() => setData(null), [])
672+
673+
return [mutate, { data, isLoading, error, reset }]
672674
}
673675

674676
export function useIsFetching() {

0 commit comments

Comments
 (0)