Skip to content

Commit c53e5ed

Browse files
committed
Merge remote-tracking branch 'react-query/master' into alpha
# Conflicts: # src/core/queryObserver.ts
2 parents 84b06ec + 2054f5b commit c53e5ed

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

docs/src/pages/reference/useQuery.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ const result = useQuery({
101101
- The time in milliseconds after data is considered stale. This value only applies to the hook it is defined on.
102102
- If set to `Infinity`, the data will never be considered stale
103103
- `cacheTime: number | Infinity`
104+
- Defaults to `5 * 60 * 1000` (5 minutes)
104105
- The time in milliseconds that unused/inactive cache data remains in memory. When a query's cache becomes unused or inactive, that cache data will be garbage collected after this duration. When different cache times are specified, the longest one will be used.
105106
- If set to `Infinity`, will disable garbage collection
106107
- `queryKeyHashFn: (queryKey: QueryKey) => string`

src/core/queryObserver.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export class QueryObserver<
6969
>
7070
private previousQueryResult?: QueryObserverResult<TData, TError>
7171
private previousSelectError: TError | null
72+
private previousSelectFn?: (data: TQueryData) => TData
7273
private staleTimeoutId?: number
7374
private refetchIntervalId?: number
7475
private currentRefetchInterval?: number | false
@@ -472,12 +473,13 @@ export class QueryObserver<
472473
if (
473474
prevResult &&
474475
state.data === prevResultState?.data &&
475-
options.select === prevResultOptions?.select &&
476+
options.select === this.previousSelectFn &&
476477
!this.previousSelectError
477478
) {
478479
data = prevResult.data
479480
} else {
480481
try {
482+
this.previousSelectFn = options.select
481483
data = options.select(state.data)
482484
if (options.structuralSharing !== false) {
483485
data = replaceEqualDeep(prevResult?.data, data)

src/reactjs/tests/useQuery.test.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4055,6 +4055,53 @@ describe('useQuery', () => {
40554055
expect(placeholderFunctionRunCount).toEqual(1)
40564056
})
40574057

4058+
it('select should only run when dependencies change if memoized', async () => {
4059+
const key1 = queryKey()
4060+
4061+
let selectRun = 0
4062+
4063+
function Page() {
4064+
const [count, inc] = React.useReducer(prev => prev + 1, 2)
4065+
4066+
const state = useQuery(
4067+
key1,
4068+
async () => {
4069+
await sleep(10)
4070+
return 0
4071+
},
4072+
{
4073+
select: React.useCallback(
4074+
(data: number) => {
4075+
selectRun++
4076+
return `selected ${data + count}`
4077+
},
4078+
[count]
4079+
),
4080+
placeholderData: 99,
4081+
}
4082+
)
4083+
4084+
return (
4085+
<div>
4086+
<h2>Data: {state.data}</h2>
4087+
<button onClick={inc}>inc: {count}</button>
4088+
</div>
4089+
)
4090+
}
4091+
4092+
const rendered = renderWithClient(queryClient, <Page />)
4093+
await waitFor(() => rendered.getByText('Data: selected 101')) // 99 + 2
4094+
expect(selectRun).toBe(1)
4095+
4096+
await waitFor(() => rendered.getByText('Data: selected 2')) // 0 + 2
4097+
expect(selectRun).toBe(2)
4098+
4099+
rendered.getByRole('button', { name: /inc/i }).click()
4100+
4101+
await waitFor(() => rendered.getByText('Data: selected 3')) // 0 + 3
4102+
expect(selectRun).toBe(3)
4103+
})
4104+
40584105
it('should cancel the query function when there are no more subscriptions', async () => {
40594106
const key = queryKey()
40604107
let cancelFn: jest.Mock = jest.fn()

0 commit comments

Comments
 (0)