- Small: 1.59 KB (minified and gzipped).
- Built-in cache: Features
stale-while-revalidate
caching from HTTP RFC 5861; users rarely see unnecessary loaders or stale data. - Revalidate cache: Automatically revalidate on interval, refocus, and network recovery; or revalidate it manually.
- Nano Stores first: Finally, fetching logic outside of components. Plays nicely with store events, computed stores,router, and the rest.
- Transport agnostic: Use GraphQL, REST codegen, plain fetch, or anything that returns Promises.
First, define the stores to set up dynamic fetching:
// core/stores.ts
import { nanoquery } from '@nanostores/query';
export const [createFetcherStore, createMutatorStore] = nanoquery({
fetcher: (...keys: string[]) => fetch(keys.join("")).then((r) => r.json()),
});
export const $currentPostId = atom<string | void>();
export const $currentPost = createFetcherStore<{ id: string; content: string }>(
["/api/post/", $currentPostId]
);
Then, use it just like a regular atom: you can compose it with all the instruments Nano Stores provides and connect it to components if you like:
// components/Post.tsx
/**
* Use lifecycle events to run side-effects, or computed stores to have derived
* state.
*/
onSet($currentPost, ({ newValue: { data: post } }) => {
if (post) trackPostVisitToAnalytics(post);
});
export const Post = () => {
// And use plain ol' hooks to get data in the component
const { data: post } = useStore($currentPost);
if (!post) return null;
return <article>{post.content}</article>;
};