본문으로 건너뛰기

useQuery

const {
data,
dataUpdatedAt,
error,
errorUpdateCount,
errorUpdatedAt,
failureCount,
failureReason,
fetchStatus,
isError,
isFetched,
isFetchedAfterMount,
isFetching,
isInitialLoading,
isLoading,
isLoadingError,
isPaused,
isPending,
isPlaceholderData,
isRefetchError,
isRefetching,
isStale,
isSuccess,
refetch,
status,
} = useQuery(
() => ({
queryKey,
queryFn,
enabled,
select,
placeholderData,
deferStream,
reconcile,
gcTime,
networkMode,
initialData,
initialDataUpdatedAt,
meta,
queryKeyHashFn,
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
retry,
retryOnMount,
retryDelay,
staleTime,
throwOnError,
}),
() => queryClient,
)

사용 예제

다음은 Solid Query에서 useQuery 프리미티브를 사용하는 방법의 몇 가지 예입니다.

기본

useQuery의 가장 기본적인 사용법은 API에서 데이터를 가져오는 쿼리를 생성하는 것입니다.

import { useQuery } from '@tanstack/solid-query'

function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))

return (
<div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}

반응형 옵션

useQuery가 객체를 반환하는 함수를 받는 이유는 반응형 옵션을 허용하기 위해서입니다. 이는 쿼리 옵션이 시간에 따라 변경될 수 있는 다른 값/신호에 의존할 때 유용합니다. Solid Query는 전달된 함수를 반응형 범위에서 추적하고 의존성이 변경될 때마다 다시 실행할 수 있습니다.

import { useQuery } from '@tanstack/solid-query'

function App() {
const [filter, setFilter] = createSignal('all')

const todos = useQuery(() => ({
queryKey: ['todos', filter()],
queryFn: async () => {
const response = await fetch(`/api/todos?filter=${filter()}`)
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
}))

return (
<div>
<div>
<button onClick={() => setFilter('all')}>All</button>
<button onClick={() => setFilter('active')}>Active</button>
<button onClick={() => setFilter('completed')}>Completed</button>
</div>
<Show when={todos.isError}>
<div>Error: {todos.error.message}</div>
</Show>
<Show when={todos.isLoading}>
<div>Loading...</div>
</Show>
<Show when={todos.isSuccess}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Show>
</div>
)
}

Suspense와 함께 사용하기

useQuery는 쿼리가 pending 또는 error 상태일 때 SolidJS SuspenseErrorBoundary 컴포넌트를 트리거하는 기능을 지원합니다. 이를 통해 컴포넌트에서 로딩 및 오류 상태를 쉽게 처리할 수 있습니다.

import { useQuery } from '@tanstack/solid-query'

function App() {
const todos = useQuery(() => ({
queryKey: 'todos',
queryFn: async () => {
const response = await fetch('/api/todos')
if (!response.ok) {
throw new Error('Failed to fetch todos')
}
return response.json()
},
throwOnError: true,
}))

return (
<ErrorBoundary fallback={<div>Error: {todos.error.message}</div>}>
<Suspense fallback={<div>Loading...</div>}>
<div>
<div>Todos:</div>
<ul>
<For each={todos.data}>{(todo) => <li>{todo.title}</li>}</For>
</ul>
</div>
</Suspense>
</ErrorBoundary>
)
}

useQuery 매개변수

  • 쿼리 옵션 - Accessor<QueryOptions>

    • queryKey: unknown[]
      • Required
      • 이 쿼리에 사용할 쿼리 키입니다.
      • 쿼리 키는 안정적인 해시로 해싱됩니다. 자세한 내용은 쿼리 키를 참조합니다.
      • 이 키가 변경되면 쿼리가 자동으로 업데이트됩니다(enabledfalse로 설정되지 않은 경우).
    • queryFn: (context: QueryFunctionContext) => Promise<TData>
      • 필수이지만 기본 쿼리 함수가 정의되지 않은 경우에만 해당합니다 자세한 내용은 기본 쿼리 함수를 참조하세요.
      • 쿼리가 데이터를 요청하는 데 사용할 함수입니다.
      • QueryFunctionContext를 받습니다
      • 데이터를 이행하거나 오류를 발생시키는 Promise를 반환해야 합니다. 데이터는 undefined일 수 없습니다.
    • enabled: boolean
      • 이 쿼리가 자동으로 실행되지 않도록 하려면 이를 false로 설정합니다.
      • 자세한 내용은 종속 쿼리에 사용할 수 있습니다.
    • select: (data: TData) => unknown
      • 선택 사항
      • 이 옵션은 쿼리 함수가 반환한 데이터의 일부를 변환하거나 선택하는 데 사용할 수 있습니다. 반환되는 data 값에는 영향을 주지만, 쿼리 캐시에 저장되는 내용에는 영향을 주지 않습니다.
      • select 함수는 data가 변경되거나 select 함수 자체에 대한 참조가 변경된 경우에만 실행됩니다. 최적화하려면 함수를 useCallback으로 래핑합니다.
    • placeholderData: TData | (previousValue: TData | undefined; previousQuery: Query | undefined,) => TData
      • 선택 사항
      • 설정하면 쿼리가 아직 pending 상태인 동안 이 값이 해당 쿼리 observer의 placeholder 데이터로 사용됩니다.
      • placeholderData는 캐시에 영구 저장되지 않습니다
      • placeholderData에 함수를 제공하면 첫 번째 인수로 이전에 관찰한 쿼리 데이터가 있는 경우 해당 데이터를 받고, 두 번째 인수로 완전한 previousQuery 인스턴스를 받습니다.
    • deferStream: boolean
      • 선택 사항
      • 기본값은 false입니다
      • 스트리밍을 사용해 서버에서 쿼리를 렌더링하는 동안에만 적용됩니다.
      • 스트림을 플러시하기 전에 서버에서 쿼리가 이행될 때까지 기다리려면 deferStreamtrue로 설정합니다.
      • 이는 쿼리가 이행되기 전에 로딩 상태를 클라이언트로 보내지 않도록 하는 데 유용할 수 있습니다.
    • reconcile: false | string | ((oldData: TData | undefined, newData: TData) => TData)
      • 선택 사항
      • 기본값은 false입니다
      • 문자열 키를 기준으로 쿼리 결과를 조정하려면 이를 문자열로 설정합니다.
      • 사용자 정의 조정 로직을 구현하려면 이전 데이터와 새 데이터를 받아 동일한 타입의 이행된 데이터를 반환하는 함수로 설정합니다.
    • gcTime: number | Infinity
      • 기본값은 5 * 60 * 1000(5분)이며, SSR 중에는 Infinity입니다
      • 사용되지 않거나 비활성 상태인 캐시 데이터가 메모리에 유지되는 시간(밀리초)입니다. 쿼리의 캐시가 사용되지 않거나 비활성 상태가 되면 이 시간이 지난 후 해당 캐시 데이터가 가비지 컬렉션됩니다. 서로 다른 가비지 컬렉션 시간이 지정되면 가장 긴 시간이 사용됩니다.
      • 참고: 허용되는 최대 시간은 약 24일이지만, timeoutManager.setTimeoutProvider를 사용하면 이 제한을 우회할 수 있습니다.
      • Infinity로 설정하면 가비지 컬렉션이 비활성화됩니다
    • networkMode: 'online' | 'always' | 'offlineFirst'
      • 선택 사항
      • 기본값은 'online'입니다
      • 자세한 내용은 네트워크 모드를 참조하세요.
    • initialData: TData | () => TData
      • 선택 사항
      • 설정하면 이 값이 쿼리 캐시의 초기 데이터로 사용됩니다(쿼리가 아직 생성되거나 캐시되지 않은 경우에 한함)
      • 함수로 설정하면 공유/루트 쿼리 초기화 중에 함수가 한 번 호출되며, initialData를 동기적으로 반환해야 합니다.
      • staleTime이 설정되지 않은 한 초기 데이터는 기본적으로 stale 상태로 간주됩니다.
      • initialData 이 캐시에 영구 저장됩니다
    • initialDataUpdatedAt: number | (() => number | undefined)
      • 선택 사항
      • 설정하면 이 값은 initialData 자체가 마지막으로 업데이트된 시간(밀리초 단위)으로 사용됩니다.
    • meta: Record<string, unknown>
      • 선택 사항
      • 설정하면 필요에 따라 사용할 수 있는 추가 정보를 쿼리 캐시 항목에 저장합니다. 이 정보는 query를 사용할 수 있는 모든 곳에서 접근할 수 있으며, queryFn에 제공되는 QueryFunctionContext의 일부이기도 합니다.
    • queryKeyHashFn: (queryKey: QueryKey) => string
      • 선택 사항
      • 지정하면 이 함수를 사용하여 queryKey를 문자열로 해시합니다.
    • refetchInterval: number | false | ((query: Query) => number | false | undefined)
      • 선택 사항
      • 숫자로 설정하면 모든 쿼리가 이 밀리초 단위 주기로 계속 다시 가져옵니다
      • 함수로 설정하면 빈도를 계산하기 위해 해당 쿼리를 인수로 함수가 실행됩니다.
    • refetchIntervalInBackground: boolean
      • 선택 사항
      • true로 설정하면 refetchInterval을 사용해 지속적으로 다시 가져오도록 설정된 쿼리는 해당 탭/창이 백그라운드에 있는 동안에도 계속 다시 가져옵니다
    • refetchOnMount: boolean | "always" | ((query: Query) => boolean | "always")
      • 선택 사항
      • 기본값은 true입니다
      • true로 설정하면 데이터가 stale 상태일 경우 쿼리가 마운트 시 다시 가져옵니다.
      • false로 설정하면 쿼리가 마운트 시 다시 가져오지 않습니다.
      • "always"으로 설정하면 쿼리가 마운트 시 항상 다시 가져옵니다.
      • 함수로 설정하면 값을 계산하기 위해 쿼리를 인자로 해당 함수가 실행됩니다
    • refetchOnWindowFocus: boolean | "always" | ((query: Query) => boolean | "always")
      • 선택 사항
      • 기본값은 true입니다
      • true로 설정하면 데이터가 stale 상태일 때 창에 포커스가 맞춰질 경우 쿼리를 다시 가져옵니다.
      • false로 설정하면 창에 포커스될 때 쿼리를 다시 가져오지 않습니다.
      • "always"으로 설정하면 창에 포커스될 때 쿼리가 항상 다시 가져옵니다.
      • 함수로 설정하면 값을 계산하기 위해 쿼리를 인자로 해당 함수가 실행됩니다
    • refetchOnReconnect: boolean | "always" | ((query: Query) => boolean | "always")
      • 선택 사항
      • 기본값은 true입니다
      • true로 설정하면 데이터가 stale 상태인 경우 다시 연결될 때 쿼리를 다시 가져옵니다.
      • false로 설정하면 다시 연결될 때 쿼리를 다시 가져오지 않습니다.
      • "always"로 설정하면 다시 연결될 때 쿼리를 항상 다시 가져옵니다.
      • 함수로 설정하면 값을 계산하기 위해 쿼리를 인자로 해당 함수가 실행됩니다
    • retry: boolean | number | (failureCount: number, error: TError) => boolean
      • false이면 실패한 쿼리는 기본적으로 재시도하지 않습니다.
      • true이면 실패한 쿼리는 무한히 재시도됩니다.
      • 예를 들어 3과 같은 number로 설정하면 실패한 쿼리 횟수가 해당 숫자에 도달할 때까지 실패한 쿼리를 재시도합니다.
      • 클라이언트에서는 기본값이 3이고 서버에서는 0입니다
    • retryOnMount: boolean | (query: Query) => boolean
      • false로 설정하면 쿼리에 오류가 있고 데이터가 없을 때 마운트 시 재시도하지 않습니다. 기본값은 true입니다.
      • 함수로 설정하면 값을 계산하기 위해 쿼리를 인수로 이 함수를 실행합니다.
    • retryDelay: number | (retryAttempt: number, error: TError) => number
      • 이 함수는 retryAttempt 정수와 실제 Error를 받아 다음 시도 전에 적용할 지연 시간을 밀리초 단위로 반환합니다.
      • attempt => Math.min(attempt > 1 ? 2 ** attempt * 1000 : 1000, 30 * 1000)과 같은 함수는 지수 백오프를 적용합니다.
      • attempt => attempt * 1000과 같은 함수는 선형 백오프를 적용합니다.
    • staleTime: number | Infinity
      • 선택 사항
      • 기본값은 0입니다
      • 데이터가 stale 상태로 간주되기까지의 시간(밀리초)입니다. 이 값은 해당 값이 정의된 훅에만 적용됩니다.
      • Infinity로 설정하면 데이터가 절대 stale 상태로 간주되지 않습니다
    • throwOnError: undefined | boolean | (error: TError, query: Query) => boolean
      • 선택 사항
      • 기본값은 false입니다
      • SSR 중에는 기본값이 true입니다
      • 사용 중단된 suspense 옵션이 true로 설정되면 기본값은 true입니다
      • 렌더링 단계에서 오류를 발생시키고 가장 가까운 error boundary로 전파하려면 이를 true로 설정하세요
      • suspense가 오류를 error boundary로 발생시키는 기본 동작을 비활성화하려면 이를 false로 설정합니다.
      • 함수로 설정하면 오류와 쿼리가 전달되며, 오류를 오류 경계에 표시할지(true) 또는 오류를 상태로 반환할지(false)를 나타내는 boolean을 반환해야 합니다.
  • Query Client - Accessor<QueryClient>

    • 선택 사항
    • 사용자 지정 QueryClient를 사용하려면 이를 사용합니다. 그렇지 않으면 가장 가까운 context의 항목이 사용됩니다.

useQuery 반환 값 - Store<QueryResult<TData, TError>>

useQuery는 다음 속성을 가진 SolidJS store를 반환합니다:

  • status: QueryStatus
    • 다음과 같습니다:
      • 캐시된 데이터가 없고 아직 완료된 쿼리 시도도 없다면 pending입니다.
      • 쿼리 시도에서 오류가 발생한 경우 error입니다. 해당 error 속성에는 가져오기 시도에서 받은 오류가 있습니다
      • 쿼리가 오류 없이 응답을 받아 데이터를 표시할 준비가 되었으면 success입니다. 쿼리의 해당 data 속성은 성공적인 가져오기로 받은 데이터이며, 쿼리의 enabled 속성이 false로 설정되어 있고 아직 가져오지 않았다면 data는 초기화 시 쿼리에 제공된 첫 번째 initialData입니다.
  • isPending: boolean
    • 편의를 위해 제공되는, 위 status 변수에서 파생된 boolean 값입니다.
  • isSuccess: boolean
    • 편의를 위해 제공되는, 위 status 변수에서 파생된 boolean 값입니다.
  • isError: boolean
    • 편의를 위해 제공되는, 위 status 변수에서 파생된 boolean 값입니다.
  • isLoadingError: boolean
    • 쿼리가 처음으로 가져오는 동안 실패하면 true가 됩니다.
  • isRefetchError: boolean
    • 다시 가져오는 동안 쿼리가 실패하면 true입니다.
  • data: Resource<TData>
    • 기본값은 undefined입니다.
    • 쿼리에서 마지막으로 성공적으로 이행된 데이터입니다.
    • 중요: data 속성은 SolidJS 리소스입니다. 즉, <Suspense> 컴포넌트 아래에서 데이터에 접근하는 경우, 데이터를 아직 사용할 수 없으면 Suspense boundary를 트리거합니다.
  • dataUpdatedAt: number
    • 쿼리가 가장 최근에 status"success"로 반환한 시점의 타임스탬프입니다.
  • error: null | TError
    • 기본값은 null입니다
    • 오류가 발생한 경우 쿼리의 오류 객체입니다.
  • errorUpdatedAt: number
    • 쿼리가 가장 최근에 status"error"로 반환한 시점의 타임스탬프입니다.
  • isStale: boolean
    • 캐시의 데이터가 무효화되었거나 데이터가 지정된 staleTime보다 오래된 경우 true가 됩니다.
  • isPlaceholderData: boolean
    • 표시된 데이터가 플레이스홀더 데이터이면 true입니다.
  • isFetched: boolean
    • 쿼리를 가져온 경우 true가 됩니다.
  • isFetchedAfterMount: boolean
    • 컴포넌트가 마운트한 후 쿼리를 가져왔다면 true가 됩니다.
    • 이 속성을 사용하면 이전에 캐시된 데이터를 표시하지 않을 수 있습니다.
  • fetchStatus: FetchStatus
    • fetching: 초기 pending과 백그라운드 다시 가져오기를 포함하여 queryFn이 실행 중일 때마다 true입니다.
    • paused: 쿼리가 가져오기를 시도했지만 paused되었습니다.
    • idle: 쿼리가 데이터를 가져오고 있지 않습니다.
    • 자세한 내용은 네트워크 모드를 참조하세요.
  • isFetching: boolean
    • 편의를 위해 제공되는, 위 fetchStatus 변수에서 파생된 boolean 값입니다.
  • isPaused: boolean
    • 편의를 위해 제공되는, 위 fetchStatus 변수에서 파생된 boolean 값입니다.
  • isRefetching: boolean
    • 백그라운드 다시 가져오기가 진행 중일 때마다 true이며, 초기 pending은 여기에 포함되지 않습니다.
    • isFetching && !isPending과 동일합니다
  • isLoading: boolean
    • 쿼리의 첫 번째 가져오기가 진행 중일 때마다 true입니다
    • isFetching && isPending과 동일합니다
  • isInitialLoading: boolean
    • 사용 중단됨
    • isLoading의 별칭이며, 다음 major 버전에서 제거됩니다.
  • failureCount: number
    • 쿼리의 실패 횟수입니다.
    • 쿼리가 실패할 때마다 증가합니다.
    • 쿼리가 성공하면 0으로 재설정합니다.
  • failureReason: null | TError
    • 쿼리 재시도의 실패 원인입니다.
    • 쿼리가 성공하면 null로 재설정합니다.
  • errorUpdateCount: number
    • 모든 오류의 합계입니다.
  • refetch: (options: { throwOnError: boolean, cancelRefetch: boolean }) => Promise<UseQueryResult>
    • 쿼리를 수동으로 다시 가져오는 함수입니다.
    • 쿼리에서 오류가 발생하면 오류는 로그에만 기록됩니다. 오류를 발생시키려면 throwOnError: true 옵션을 전달합니다
    • cancelRefetch?: boolean
      • 기본값은 true입니다
        • 기본적으로 새 요청을 보내기 전에 현재 실행 중인 요청이 취소됩니다
      • false로 설정하면 이미 요청이 실행 중일 때 다시 가져오기를 수행하지 않습니다.