# Nano Stores Query

> A data fetcher library for Nano Stores state manager.

- URL: https://evilmartians.com/opensource/nano-stores-query
- GitHub: https://github.com/nanostores/query
- Authors: Dan Kozlov

---

Nano Stores Query is a data fetcher library for the [Nano Stores](https://evilmartians.com/opensource/nano-stores) state manager that brings both UX and DX for remote data-driven apps to the sky.

- **Small**: 1.59 KB (minified and gzipped).
- **Built-in cache**: Features `stale-while-revalidate` caching from [HTTP RFC 5861](https://tools.ietf.org/html/rfc5861); 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](https://github.com/nanostores/nanostores#store-events), [computed stores](https://github.com/nanostores/nanostores#computed-stores),[router](https://github.com/nanostores/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:

```ts
// 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:

```tsx
// 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>;
};
```
