forked from TanStack/query
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseQueryState.ts
67 lines (60 loc) · 1.65 KB
/
useQueryState.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
'use client'
import * as React from 'react'
import { notifyManager, replaceEqualDeep } from '@tanstack/query-core'
import { useQueryClient } from './QueryClientProvider'
import type {
DefaultError,
Query,
QueryCache,
QueryClient,
QueryFilters,
QueryKey,
QueryState,
} from '@tanstack/query-core'
type QueryStateOptions<TResult = QueryState> = {
filters?: QueryFilters
select?: (query: Query<unknown, DefaultError, unknown, QueryKey>) => TResult
}
function getResult<TResult = QueryState>(
queryCache: QueryCache,
options: QueryStateOptions<TResult>,
): Array<TResult> {
return queryCache
.findAll(options.filters)
.map(
(query): TResult =>
(options.select ? options.select(query) : query.state) as TResult,
)
}
export function useQueryState<TResult = QueryState>(
options: QueryStateOptions<TResult> = {},
queryClient?: QueryClient,
): Array<TResult> {
const queryCache = useQueryClient(queryClient).getQueryCache()
const optionsRef = React.useRef(options)
const result = React.useRef<Array<TResult>>()
if (!result.current) {
result.current = getResult(queryCache, options)
}
React.useEffect(() => {
optionsRef.current = options
})
return React.useSyncExternalStore(
React.useCallback(
(onStoreChange) =>
queryCache.subscribe(notifyManager.batchCalls(onStoreChange)),
[queryCache],
),
() => {
const nextResult = replaceEqualDeep(
result.current,
getResult(queryCache, optionsRef.current),
)
if (result.current !== nextResult) {
result.current = nextResult
}
return result.current
},
() => result.current,
)!
}