Skip to content

useQuery

useQuery(query) читает per-scope состояние query и возвращает колбэки, привязанные к предоставленному скоупу. Под капотом это useUnit — без кеша, без опций, один аргумент.

tsx
import { useQuery } from "@virentia/net-react";
import { searchQuery } from "./model";

function Search() {
  const search = useQuery(searchQuery);

  return (
    <>
      <input onChange={(e) => void search.run({ text: e.target.value })} />
      {search.pending && <Spinner />}
      {search.error && <ErrorBox error={search.error} retry={search.refetch} />}
      <Results items={search.data ?? []} stale={search.stale} />
    </>
  );
}

Результат

ПолеТипЗначение
dataData | nullпоследний успех в этом скоупе (initialData до первого запуска)
errorErr | nullпоследняя ошибка; снова null после успеха
pendingbooleanзапуск в полёте
stalebooleanвыставляется cache(); без него — false
run(params)(params: Raw) => Promise<Data>запустить query в предоставленном скоупе
refetch()() => Promise<void>повторить последние params этого скоупа (no-op, если query там не запускалась)
reset()() => Promise<void>очистить data, прервать запуски в полёте

Все чтения реактивны: компонент ререндерится, когда значения сторов меняются в предоставленном скоупе — и только тогда. Два компонента под разными ScopeProvider видят независимые data и pending.

Заметки

  • run возвращает промис query: await в обработчике даёт загруженное значение или бросает ошибку — тот же контракт, что у вызова query в scoped.
  • Хук не запускает query. Загрузка при монтировании — работа модели: триггер на роуте или событии — тогда SSR, тесты и компонент рендерят одно и то же поведение.
  • Нужно одно поле? useUnit(searchQuery.pending) работает как обычно: useQuery — удобство, а не требование.