본문으로 건너뛰기

쿼리

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를 읽기 전에 pendingerror를 확인한 후 해당 타입을 좁힙니다.

가져오기 상태

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>`

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