@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-reactHow 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.tsJSDoc, 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; ornull.
Returns: The document's state.
Injection Notes
Requirements
Peer dependencies:
@molecule/app-query^1.0.0react^18.0.0 || ^19.0.0
Runtime Dependencies
-
@molecule/app-query -
react -
useQueryreads the cache synchronously on the first render. A document prefetched from a hovered link, or seeded withclient.set()from a server-rendered JSON island, renders at once — no spinner, no layout shift. Render a loading state only whendataisundefined. -
The key is the identity. Building
optionsinline is fine; the hook resubscribes only when the key's value changes, not when thefetchclosure does. -
intentPrefetchPropsspreads 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'anderror. A refetch after an error is one more subscription (a re-mount or a key change) or aclient.invalidate().