QueryKeys
The QueryKeys
class manages React Query keys and provides methods for cache operations like invalidation, refetching, and data retrieval. It's automatically created and used internally by QueryManager.
Key Generation
The QueryKeys class generates consistent query keys for different operations:
// Internal key structure
{
list: ['users', 'list'],
retrieve: (id) => ['users', 'retrieve', id],
create: ['users', 'create'],
update: ['users', 'update'],
delete: ['users', 'delete']
}
List Keys with Filters
List query keys automatically include filters when present:
// Without filters: ['users', 'list']
// With filters: ['users', 'list', { status: 'active', search: 'john' }]
const queryKey = queryKeys.listKeyWithFilters({ status: 'active' })
// Result: ['users', 'list', { status: 'active' }]
Cache Operations
Invalidation
// Access QueryKeys from QueryManager instance
const { queryKeys } = userQueryManager
// Invalidate all queries for this resource
await queryKeys.invalidateAll()
// Invalidate all list queries
await queryKeys.invalidateList()
// Invalidate list queries with specific filters
await queryKeys.invalidateList({ status: 'active' })
// Invalidate specific retrieve query
await queryKeys.invalidateRetrieve('user-123')
// Invalidate with options
await queryKeys.invalidateAll(
{ exact: true },
{ cancelRefetch: false }
)
Refetching
// Refetch all queries
await queryKeys.refetchAll()
// Refetch list queries
await queryKeys.refetchList()
// Refetch list queries with filters, ignoring specific query keys
await queryKeys.refetchList(
{ status: 'active' }, // filters
[['users', 'list', { status: 'inactive' }]] // ignore these keys
)
// Refetch specific retrieve query
await queryKeys.refetchRetrieve('user-123')
Data Retrieval
// Get list data from cache
const { items, itemMap } = queryKeys.getListData()
console.log('Cached users:', items)
console.log('User map:', itemMap['user-123'])
// Get list data with filters
const { items: activeUsers } = queryKeys.getListData({ status: 'active' })
// Get retrieve data from cache
const user = queryKeys.getRetrieveData('user-123')
console.log('Cached user:', user)
// Get retrieve data only from specific query (not from list cache)
const userFromQuery = queryKeys.getRetrieveData('user-123', true)
Query Management
// Cancel in-flight list queries
await queryKeys.cancelListQueries()
// Cancel specific list queries with filters
await queryKeys.cancelListQueries({ status: 'active' })
// Remove query data from cache
await queryKeys.removeRetrieveQueryData('user-123')
// Get all list queries
const listQueries = queryKeys.getAllListQueries()
console.log('Active list queries:', listQueries.length)
Practical Examples
Smart Cache Invalidation
function useUserActions() {
const { queryKeys } = userQueryManager
const handleUserStatusChange = async (userId: string) => {
// Invalidate the specific user
await queryKeys.invalidateRetrieve(userId)
// Invalidate all list queries since status affects filtering
await queryKeys.invalidateList()
}
const handleUserRoleChange = async (userId: string) => {
// Only invalidate lists that might be affected by role changes
await queryKeys.invalidateRetrieve(userId)
await queryKeys.invalidateList({ role: 'admin' })
await queryKeys.invalidateList({ role: 'user' })
}
return { handleUserStatusChange, handleUserRoleChange }
}
Background Refetching
function useBackgroundSync() {
const { queryKeys } = userQueryManager
useEffect(() => {
const interval = setInterval(async () => {
// Refetch stale data in background
await queryKeys.refetchAll(
{ type: 'active' }, // only active queries
{ cancelRefetch: false } // don't cancel ongoing requests
)
}, 5 * 60 * 1000) // every 5 minutes
return () => clearInterval(interval)
}, [])
}