본문으로 건너뛰기

쿼리

Lit Query를 처음 사용하시나요? 요소에 쿼리 컨트롤러를 연결하기 전에 설치와 빠른 시작부터 살펴보세요.

쿼리 기본 사항​

쿼리는 고유한 키에 연결된 비동기 데이터 소스에 대한 선언적 의존성입니다. 서버 상태를 읽을 때 쿼리를 사용하세요. 함수가 서버 데이터를 생성, 업데이트 또는 삭제한다면 대신 뮤테이션을 사용하세요.

Lit에서는 createQueryController를 사용하여 쿼리를 구독합니다:

import { LitElement, html } from 'lit'
import { createQueryController } from '@tanstack/lit-query'

class TodosView extends LitElement {
private readonly todos = createQueryController(this, {
queryKey: ['todos'],
queryFn: fetchTodos,
})

render() {
const query = this.todos()

if (query.isPending) return html`Loading...`
if (query.isError) return html`Error: ${query.error.message}`

return html`
<ul>
${query.data.map((todo) => html`<li>${todo.title}</li>`)}
</ul>
`
}
}

컨트롤러에 필요한 항목:

  • ReactiveControllerHost이며, 일반적으로 LitElement 내부의 this입니다
  • 고유한 queryKey
  • Promise를 반환하고 오류 발생 시 오류를 발생시키는 queryFn

반환된 accessor는 현재 QueryObserverResult를 노출합니다. render에서 호출하거나 .current를 읽으세요:

const query = this.todos()
const sameQuery = this.todos.current

쿼리 상태​

쿼리는 한 번에 하나의 기본 상태일 수 있습니다:

  • isPending 또는 status === 'pending': 아직 사용 가능한 데이터가 없습니다
  • isError 또는 status === 'error': 쿼리가 실패했으며 error를 사용할 수 있습니다
  • isSuccess 또는 status === 'success': 데이터를 사용할 수 있습니다.

결과에는 isFetching도 포함되며, 초기 로드 또는 백그라운드 다시 가져오기 중에 true일 수 있습니다.

render() {
const query = this.todos()

if (query.status === 'pending') {
return html`<span>Loading...</span>`
}

if (query.status === 'error') {
return html`<span>Error: ${query.error.message}</span>`
}

return html`<todo-list .items=${query.data}></todo-list>`
}

TypeScript는 query.data를 읽기 전에 pending과 error를 확인한 후 해당 타입을 좁힙니다.

가져오기 상태​

status 필드는 데이터의 사용 가능 여부를 나타냅니다. fetchStatus 필드는 쿼리 함수가 수행 중인 작업을 나타냅니다:

  • fetchStatus === 'fetching': 쿼리가 현재 가져오는 중입니다.
  • fetchStatus === 'paused': 쿼리가 가져오기를 원했지만 가져오기가 일시 중지되었습니다.
  • fetchStatus === 'idle': 쿼리가 데이터를 가져오고 있지 않습니다.

이러한 상태는 의도적으로 분리되어 있습니다. 백그라운드 다시 가져오기 및 stale-while-revalidate 동작으로 인해 다음과 같은 조합이 발생할 수 있습니다:

  • 캐시된 데이터가 있는 성공한 쿼리는 백그라운드 다시 가져오기가 실행되는 동안 status === 'success' 및 fetchStatus === 'fetching'을 가질 수 있습니다.
  • 데이터가 없는 쿼리는 가져오기를 아직 시작할 수 없는 경우 status === 'pending' 및 fetchStatus === 'paused' 상태일 수 있습니다.

데이터를 렌더링할 수 있는지 결정할 때는 status를 사용하고, 네트워크 활동 표시기를 표시할지 결정할 때는 fetchStatus 또는 isFetching을 사용합니다:

render() {
const query = this.todos()

if (query.isPending) return html`Loading...`
if (query.isError) return html`Error: ${query.error.message}`

return html`
${query.fetchStatus === 'fetching'
? html`<span>Refreshing...</span>`
: null}
<todo-list .items=${query.data}></todo-list>
`
}

반응형 쿼리 옵션​

쿼리 키 또는 쿼리 함수가 호스트 상태에 종속되는 경우 옵션 getter를 사용합니다:

class UserTodos extends LitElement {
static properties = {
userId: { type: String },
}

userId = ''

private readonly todos = createQueryController(this, () => ({
queryKey: ['todos', this.userId],
queryFn: () => fetchTodos(this.userId),
enabled: this.userId.length > 0,
}))
}

쿼리 키는 캐싱, 다시 가져오기 및 컨트롤러 간 데이터 공유에 사용됩니다.

다시 가져오기​

접근자에는 refetch가 포함됩니다:

html`<button @click=${() => this.todos.refetch()}>Refetch</button>`

동시에 실행해야 하는 여러 쿼리에 대해서는 병렬 쿼리를 참조하세요.