Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(useQueries): make sure we don't lose property tracking #8295

Merged
merged 2 commits into from
Nov 15, 2024
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
33 changes: 21 additions & 12 deletions packages/query-core/src/queriesObserver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,21 +175,30 @@
return this.#combineResult(r ?? result, combine)
},
() => {
return matches.map((match, index) => {
const observerResult = result[index]!
return !match.defaultedQueryOptions.notifyOnChangeProps
? match.observer.trackResult(observerResult, (accessedProp) => {
// track property on all observers to ensure proper (synchronized) tracking (#7000)
matches.forEach((m) => {
m.observer.trackProp(accessedProp)
})
})
: observerResult
})
return this.#trackResult(result, queries)

Check warning on line 178 in packages/query-core/src/queriesObserver.ts

View check run for this annotation

Codecov / codecov/patch

packages/query-core/src/queriesObserver.ts#L178

Added line #L178 was not covered by tests
},
]
}

#trackResult(
result: Array<QueryObserverResult>,
queries: Array<QueryObserverOptions>,
) {
const matches = this.#findMatchingObservers(queries)

return matches.map((match, index) => {
const observerResult = result[index]!
return !match.defaultedQueryOptions.notifyOnChangeProps
? match.observer.trackResult(observerResult, (accessedProp) => {
// track property on all observers to ensure proper (synchronized) tracking (#7000)
matches.forEach((m) => {
m.observer.trackProp(accessedProp)

Check warning on line 195 in packages/query-core/src/queriesObserver.ts

View check run for this annotation

Codecov / codecov/patch

packages/query-core/src/queriesObserver.ts#L194-L195

Added lines #L194 - L195 were not covered by tests
})
})
: observerResult

Check warning on line 198 in packages/query-core/src/queriesObserver.ts

View check run for this annotation

Codecov / codecov/patch

packages/query-core/src/queriesObserver.ts#L198

Added line #L198 was not covered by tests
})
}

#combineResult(
input: Array<QueryObserverResult>,
combine: CombineFn<TCombinedResult> | undefined,
Expand Down Expand Up @@ -267,7 +276,7 @@
if (this.hasListeners()) {
const previousResult = this.#combinedResult
const newResult = this.#combineResult(
this.#result,
this.#trackResult(this.#result, this.#queries),
this.#options?.combine,
)

Expand Down
73 changes: 73 additions & 0 deletions packages/react-query/src/__tests__/useQueries.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1548,4 +1548,77 @@ describe('useQueries', () => {
// one with pending, one with foo
expect(renders).toBe(2)
})

it('should track properties correctly with combine', async () => {
const key1 = queryKey()
const key2 = queryKey()
const key3 = queryKey()

const client = new QueryClient()

function Page() {
const data = useQueries(
{
queries: [
{
queryKey: [key1],
queryFn: async () => {
await sleep(10)
return 'first result'
},
},
{
queryKey: [key2],
queryFn: async () => {
await sleep(15)
return 'second result'
},
},
{
queryKey: [key3],
queryFn: async () => {
await sleep(20)
return 'third result'
},
},
],
combine: (results) => {
if (results.find((r) => r.isPending)) {
return 'pending'
}
return results.map((r) => r.data).join(', ')
},
},
client,
)

return (
<div>
<div>data: {data}</div>
<button
onClick={() => {
client.setQueryData([key1], 'first result updated')
}}
>
update
</button>
</div>
)
}

const rendered = render(<Page />)

await waitFor(() => rendered.getByText('data: pending'))
await waitFor(() =>
rendered.getByText('data: first result, second result, third result'),
)

fireEvent.click(rendered.getByRole('button', { name: /update/i }))

await waitFor(() =>
rendered.getByText(
'data: first result updated, second result, third result',
),
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,6 @@ describe('useSuspenseQueries 2', () => {
queryKey: key,
queryFn: async () => {
count++
console.log('queryFn')
throw new Error('Query failed')
},
gcTime: 0,
Expand Down
Loading