Skip to content

Commit

Permalink
fix(refetch): force refetch when variables resolve to identical query…
Browse files Browse the repository at this point in the history
… key
  • Loading branch information
ismay committed Aug 9, 2021
1 parent ba53691 commit 524eb3e
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 3 deletions.
1 change: 1 addition & 0 deletions services/data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"coverage": "yarn test --coverage"
},
"dependencies": {
"fast-safe-stringify": "^2.0.8",
"react-query": "^3.13.11"
}
}
46 changes: 44 additions & 2 deletions services/data/src/react/hooks/useDataQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,8 @@ describe('useDataQuery', () => {

/**
* FIXME: https://github.com/tannerlinsley/react-query/issues/2481
* It's unclear whether this rerender being necessary is intentional
* or a bug.
* This forced rerender is not necessary in the app, just when testing.
* It is unclear why.
*/
rerender()
})
Expand Down Expand Up @@ -585,6 +585,48 @@ describe('useDataQuery', () => {
})
})

it('Should refetch when refetch is called with variables that resolve to the same query key', async () => {
const variables = { one: 1, two: 2, three: 3 }
const query = {
x: {
resource: 'answer',
params: ({ one, two, three }) => ({ one, two, three }),
},
}
const spy = jest.fn(() => 42)
const data = { answer: spy }
const wrapper = ({ children }) => (
<CustomDataProvider data={data}>{children}</CustomDataProvider>
)

const { result, waitForNextUpdate } = renderHook(
() => useDataQuery(query, { variables }),
{ wrapper }
)

await waitForNextUpdate()

expect(spy).toHaveBeenCalledTimes(1)
expect(result.current).toMatchObject({
loading: false,
called: true,
data: { x: 42 },
})

act(() => {
result.current.refetch({ variables })
})

await waitForNextUpdate()

expect(spy).toHaveBeenCalledTimes(2)
expect(result.current).toMatchObject({
loading: false,
called: true,
data: { x: 42 },
})
})

it('Should return a promise that resolves with the data on success when refetching and lazy', async () => {
const query = { x: { resource: 'answer' } }
const data = { answer: 42 }
Expand Down
16 changes: 15 additions & 1 deletion services/data/src/react/hooks/useDataQuery.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import stringify from 'fast-safe-stringify'
import { useState, useRef } from 'react'
import { useQuery, setLogger } from 'react-query'
import { Query, QueryOptions } from '../../engine'
Expand Down Expand Up @@ -103,7 +104,20 @@ export const useDataQuery = (
}

if (newVariables) {
setVariables({ ...variables, ...newVariables })
const merged = { ...variables, ...newVariables }
const identical =
stringify.stableStringify(variables) ===
stringify.stableStringify(merged)

setVariables(merged)

// If the variables are identical we'll need to trigger the refetch manually
if (identical) {
return queryRefetch({
cancelRefetch: true,
throwOnError: false,
}).then(({ data }) => data)
}
}

// This promise does not currently reject on errors
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6434,6 +6434,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=

fast-safe-stringify@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz#dc2af48c46cf712b683e849b2bbd446b32de936f"
integrity sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==

fastq@^1.6.0:
version "1.11.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
Expand Down

0 comments on commit 524eb3e

Please sign in to comment.