@molecule/app-query-react

Feature · query · App (browser) · v1.0.1 · Apache-2.0

React hooks for @molecule/app-query — read a cached document synchronously, observe it, and prefetch on intent

npm install @molecule/app-query-react

npm · Source on GitHub

How it works

@molecule/app-query-react is a ready-made query feature for the app (browser) side. It composes the core interfaces it needs, so it works with whichever providers your app has bonded.

import { intentPrefetchProps, useQuery } from '@molecule/app-query-react'

const packageQuery = (name: string) => ({
  key: ['package', name],
  fetch: (signal: AbortSignal) =>
    fetch(`/data/packages/${name}.json`, { signal }).then((r) => r.json()),
})

function PackageLink({ name }: { name: string }) {
  return (
    <Link to={`/packages/${name}`} {...intentPrefetchProps(packageQuery(name))}>
      {name}
    </Link>
  )
}

function PackagePage({ name }: { name: string }) {
  const { data, status } = useQuery(packageQuery(name))
  if (!data) return status === 'error' ? <NotFound /> : <Skeleton />
  return <Article doc={data} />
}

Works with: @molecule/app-query

Reference

React hooks for @molecule/app-query.

useQuery observes one document from the app's shared cache and returns cached data on the first render; usePrefetch and intentPrefetchProps warm a document when a person is about to open it. Together they make a detail page open with no loading state.

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Quick Start

import { intentPrefetchProps, useQuery } from '@molecule/app-query-react'

const packageQuery = (name: string) => ({
  key: ['package', name],
  fetch: (signal: AbortSignal) =>
    fetch(`/data/packages/${name}.json`, { signal }).then((r) => r.json()),
})

function PackageLink({ name }: { name: string }) {
  return (
    <Link to={`/packages/${name}`} {...intentPrefetchProps(packageQuery(name))}>
      {name}
    </Link>
  )
}

function PackagePage({ name }: { name: string }) {
  const { data, status } = useQuery(packageQuery(name))
  if (!data) return status === 'error' ? <NotFound /> : <Skeleton />
  return <Article doc={data} />
}

Type

feature

Installation

npm install @molecule/app-query-react @molecule/app-query react
npm install -D @types/react

API

Interfaces

IntentPrefetchProps

The handlers intentPrefetchProps returns.

interface IntentPrefetchProps {
  onPointerEnter: () => void
  onFocus: () => void
  onTouchStart: () => void
}

Functions

prefetchQuery(options)

Warms the cache for a document, when the connection can afford it (see shouldPrefetch() in the core). Safe to call repeatedly: a fresh or in-flight document is skipped, and failures are swallowed.

function prefetchQuery(options: QueryOptions<T>): void
  • options — Key, fetch, freshness.

usePrefetch()

A stable prefetch(options) function for event handlers.

function usePrefetch(): <T>(options: QueryOptions<T>) => void

Returns: The prefetch function.

intentPrefetchProps(options)

Event handlers that warm a document at the first sign of intent: the pointer arriving, keyboard focus, or a touch starting. Spread them onto a link: <Link {...intentPrefetchProps(packageQuery(name))} />.

function intentPrefetchProps(options: QueryOptions<T>): IntentPrefetchProps
  • options — Key, fetch, freshness.

Returns: The handlers.

useQuery(options)

The document for options.key, kept current: cached data is returned on the very first render (so a warmed page never flashes a loading state), a stale or missing document is fetched, and every change re-renders. Pass null to observe nothing. A key change resets to that key's state; the hook never hands a caller another key's document.

function useQuery(options: QueryOptions<T> | null): QueryState<T>
  • options — Key, fetch, freshness; or null.

Returns: The document's state.

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-query ^1.0.0
  • react ^18.0.0 || ^19.0.0

Runtime Dependencies

  • @molecule/app-query

  • react

  • useQuery reads the cache synchronously on the first render. A document prefetched from a hovered link, or seeded with client.set() from a server-rendered JSON island, renders at once — no spinner, no layout shift. Render a loading state only when data is undefined.

  • The key is the identity. Building options inline is fine; the hook resubscribes only when the key's value changes, not when the fetch closure does.

  • intentPrefetchProps spreads three handlers onto a link. It is a plain function (not a hook), so it works inside .map() too.

  • Prefetching respects the browser's data-saver setting and skips 2G connections (shouldPrefetch() in the core) — do not bypass that for "important" links; the person can still click.

  • Errors are not thrown from the hook; read status === 'error' and error. A refetch after an error is one more subscription (a re-mount or a key change) or a client.invalidate().