TanStack Query manages caching by query key. Query keys must be arrays at the top level, and they should uniquely describe the data returned by the query function.
Use simple keys for list resources or non-hierarchical data:
createQueryController(this, {
queryKey: ['todos'],
queryFn: fetchTodos,
})
createQueryController(this, {
queryKey: ['settings'],
queryFn: fetchSettings,
})createQueryController(this, {
queryKey: ['todos'],
queryFn: fetchTodos,
})
createQueryController(this, {
queryKey: ['settings'],
queryFn: fetchSettings,
})Include variables when they change what the query fetches:
createQueryController(this, () => ({
queryKey: ['todo', this.todoId],
queryFn: () => fetchTodo(this.todoId),
}))
createQueryController(this, () => ({
queryKey: ['projects', { page: this.page, filter: this.filter }],
queryFn: () => fetchProjects({ page: this.page, filter: this.filter }),
}))createQueryController(this, () => ({
queryKey: ['todo', this.todoId],
queryFn: () => fetchTodo(this.todoId),
}))
createQueryController(this, () => ({
queryKey: ['projects', { page: this.page, filter: this.filter }],
queryFn: () => fetchProjects({ page: this.page, filter: this.filter }),
}))The pagination example uses a key shaped like this:
type ProjectsQueryKey = readonly ['projects', number, number, boolean]
function projectsQueryKey(
page: number,
delayMs: number,
forceError: boolean,
): ProjectsQueryKey {
return ['projects', page, delayMs, forceError] as const
}type ProjectsQueryKey = readonly ['projects', number, number, boolean]
function projectsQueryKey(
page: number,
delayMs: number,
forceError: boolean,
): ProjectsQueryKey {
return ['projects', page, delayMs, forceError] as const
}Object key order does not matter inside a query key:
const keyA = ['todos', { status, page }]
const keyB = ['todos', { page, status }]const keyA = ['todos', { status, page }]
const keyB = ['todos', { page, status }]Array item order does matter:
const keyA = ['todos', status, page]
const keyB = ['todos', page, status]const keyA = ['todos', status, page]
const keyB = ['todos', page, status]If your query function reads a reactive host property, include that value in the query key:
class UserTodos extends LitElement {
userId = ''
private readonly todos = createQueryController(this, () => ({
queryKey: ['todos', this.userId],
queryFn: () => fetchTodos(this.userId),
}))
}class UserTodos extends LitElement {
userId = ''
private readonly todos = createQueryController(this, () => ({
queryKey: ['todos', this.userId],
queryFn: () => fetchTodos(this.userId),
}))
}This lets Lit Query cache each user's todos separately and refetch when the host state changes.