77 lines
2.1 KiB
Markdown
77 lines
2.1 KiB
Markdown
# qk-hierarchical-organization: Organize Keys Hierarchically
|
|
|
|
## Priority: CRITICAL
|
|
|
|
## Explanation
|
|
|
|
Structure query keys from general to specific: entity type first, then ID, then modifiers/filters. This enables efficient invalidation at any level of specificity and creates predictable cache organization.
|
|
|
|
## Bad Example
|
|
|
|
```tsx
|
|
// Flat, inconsistent key structures
|
|
const { data: todos } = useQuery({
|
|
queryKey: ['all-todos-list'],
|
|
queryFn: fetchTodos,
|
|
})
|
|
|
|
const { data: todo } = useQuery({
|
|
queryKey: ['single-todo-5'],
|
|
queryFn: () => fetchTodo(5),
|
|
})
|
|
|
|
const { data: comments } = useQuery({
|
|
queryKey: ['todo-5-comments'],
|
|
queryFn: () => fetchTodoComments(5),
|
|
})
|
|
|
|
// Can't easily invalidate all todo-related queries
|
|
```
|
|
|
|
## Good Example
|
|
|
|
```tsx
|
|
// Hierarchical: entity → id → sub-resource → filters
|
|
const { data: todos } = useQuery({
|
|
queryKey: ['todos'],
|
|
queryFn: fetchTodos,
|
|
})
|
|
|
|
const { data: todo } = useQuery({
|
|
queryKey: ['todos', 5],
|
|
queryFn: () => fetchTodo(5),
|
|
})
|
|
|
|
const { data: comments } = useQuery({
|
|
queryKey: ['todos', 5, 'comments'],
|
|
queryFn: () => fetchTodoComments(5),
|
|
})
|
|
|
|
const { data: filteredTodos } = useQuery({
|
|
queryKey: ['todos', { status: 'done', page: 1 }],
|
|
queryFn: () => fetchTodos({ status: 'done', page: 1 }),
|
|
})
|
|
|
|
// Now we can invalidate at any level:
|
|
queryClient.invalidateQueries({ queryKey: ['todos'] }) // All todos
|
|
queryClient.invalidateQueries({ queryKey: ['todos', 5] }) // Todo 5 and its sub-resources
|
|
queryClient.invalidateQueries({ queryKey: ['todos', 5, 'comments'] }) // Just comments
|
|
```
|
|
|
|
## Recommended Hierarchy Pattern
|
|
|
|
```
|
|
['entity'] // List
|
|
['entity', id] // Single item
|
|
['entity', id, 'sub-resource'] // Related data
|
|
['entity', { filters }] // Filtered list
|
|
['entity', id, 'sub-resource', { filters }] // Filtered sub-resource
|
|
```
|
|
|
|
## Context
|
|
|
|
- Essential for applications with related data
|
|
- Enables efficient cache management
|
|
- Works with prefix-based invalidation
|
|
- Consider using query key factories (see `qk-factory-pattern`) for consistency
|