- Small. 1.65 Kb (minified and gzipped).
- Built-in cache.
stale-while-revalidate
caching from HTTP RFC 5861. A user rarely sees 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, you 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, you use it just as a regular atom: you can compose it with all the instruments Nano Stores provides you with 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' hook to get the data in the component
const { data: post } = useStore($currentPost);
if (!post) return null;
return <article>{post.content}</article>;
};