-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseQueryRefreshControlProps.ts
More file actions
66 lines (59 loc) · 2.53 KB
/
useQueryRefreshControlProps.ts
File metadata and controls
66 lines (59 loc) · 2.53 KB
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
import type { QueryKey, UseInfiniteQueryResult, UseQueryResult } from '@tanstack/react-query'
import type { RefreshControlProps } from 'react-native'
import { useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
type UseGenericQueryResult = UseInfiniteQueryResult<any, any> | UseQueryResult<any, any>
/**
* A React hook that provides RefreshControl props for React Native ScrollView/FlatList components
* that automatically refetches multiple React Query queries when pulled to refresh.
*
* @param queries - Array of React Query results (useQuery or useInfiniteQuery) to refetch on refresh.
* Only queries that are fetched or currently fetching will be refetched.
* @param invalidateQueryKeys - Optional array of query keys to invalidate after refetch completes
* @param RefreshControlProps - Optional additional RefreshControl props to merge with the generated ones
* @returns RefreshControl props object with onRefresh and refreshing state
*
* @example
* Basic usage with multiple queries:
* ```typescript
* const usersQuery = useQuery({ queryKey: ['users'], queryFn: fetchUsers })
* const postsQuery = useQuery({ queryKey: ['posts'], queryFn: fetchPosts })
* const refreshControlProps = useQueryRefreshControlProps([usersQuery, postsQuery])
* // Use with ScrollView: refreshControl={<RefreshControl {...refreshControlProps} />}
* ```
*
* @example
* Usage with query invalidation:
* ```typescript
* const postsQuery = useQuery({ queryKey: ['posts'], queryFn: fetchPosts })
* const refreshControlProps = useQueryRefreshControlProps(
* [postsQuery],
* [['notifications'], ['unreadCount']], // Invalidate these queries on refresh
* { tintColor: '#ff0000' }
* )
* // Use with FlatList: refreshControl={<RefreshControl {...refreshControlProps} />}
* ```
*/
export function useQueryRefreshControlProps(
queries: UseGenericQueryResult[],
invalidateQueryKeys?: QueryKey[],
RefreshControlProps?: RefreshControlProps,
) {
const [refreshing, setRefreshing] = useState(false)
const queryClient = useQueryClient()
async function onRefresh() {
RefreshControlProps?.onRefresh?.()
setRefreshing(true)
try {
await Promise.all(queries.filter((q) => q.isFetched || q.isFetching).map((query) => query.refetch()))
if (invalidateQueryKeys?.length) {
invalidateQueryKeys.forEach((queryKey) => {
queryClient.invalidateQueries({ queryKey })
})
}
} finally {
setRefreshing(false)
}
}
return { ...RefreshControlProps, onRefresh, refreshing }
}