Skip to content
Back to skills

Recipes

ASecurity

Concrete copy-paste recipes for common `@mongez/react-atom` patterns: toggles, modals with payload, fetch flows, granular subscriptions, SSR hydration, SSR-safe action handlers, and devtools setup. TRIGGER when: code mixes preset atoms (`openAtom`, `portalAtom`, `fetchingAtom`) with handlers, `AtomStoreProvider` + `HydrateAtomsScript` + `readHydration`, or calls `useAtom(template)` from an event handler; user asks "how do I wire up a modal with portalAtom", "how do I do a fetch flow with fetc...

  • 9 stars
  • 0 votes
  • 0 copies
  • 9 views
  • Added May 28, 2026
developmentgoreactnextjsnodegitapi

Works with

  • cli
  • api

Security analysis

A100/100

Scanned May 28, 2026

npx -y skills add hassanzohdy/mongez-react-atom --skill recipes --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Recipes?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Recipes
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/hassanzohdy-recipes/badge)](https://www.skillsdirectory.com/skills/hassanzohdy-recipes)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mongez-react-atom-recipes
description: |
  Concrete copy-paste recipes for common `@mongez/react-atom` patterns: toggles, modals with payload, fetch flows, granular subscriptions, SSR hydration, SSR-safe action handlers, and devtools setup.
  TRIGGER when: code mixes preset atoms (`openAtom`, `portalAtom`, `fetchingAtom`) with handlers, `AtomStoreProvider` + `HydrateAtomsScript` + `readHydration`, or calls `useAtom(template)` from an event handler; user asks "how do I wire up a modal with portalAtom", "how do I do a fetch flow with fetchingAtom", "how do I subscribe to a single object key", "how do I call an action method safely under SSR", or "how do I enable Redux DevTools for atoms"; user wants a working end-to-end example, not just an API description; typical import `import { openAtom, portalAtom, fetchingAtom, useAtom } from "@mongez/react-atom"`.
  SKIP: a single-API reference (use `mongez-react-atom-atoms`, `mongez-react-atom-presets`, or `mongez-react-atom-ssr` instead — recipes is for combined patterns); the underlying framework-agnostic atom primitive lives in `@mongez/atom`; server-state caching with query keys belongs in `@mongez/atomic-query`.
---
# Recipes

Common flows across the React adapter's features.

## Toggle + content separation

```ts
const sidebar = openAtom("sidebar");

function Toggle() {
  return <button onClick={() => sidebar.toggle()}>≡</button>;
}

function Sidebar() {
  const opened = sidebar.useOpened();
  return opened ? <Drawer /> : null;
}
```

## Modal with payload

```ts
const editUserModal = portalAtom<{ id: number; initialName: string }>("editUser");

// From a list:
<button onClick={() => editUserModal.open({ id: u.id, initialName: u.name })}>Edit</button>

// In the modal component:
function EditUserModal() {
  const opened = editUserModal.useOpened();
  const data = editUserModal.useData();
  if (!opened) return null;
  return <Dialog onClose={() => editUserModal.close()}>...{data.initialName}...</Dialog>;
}
```

## Fetch flow with `fetchingAtom`

```ts
const usersAtom = fetchingAtom<User[]>("users");

export async function loadUsers() {
  usersAtom.startLoading();
  try {
    const data = await api.users.list();
    usersAtom.success(data);
  } catch (err) {
    usersAtom.failed(err);
  }
}

function UsersList() {
  const isLoading = usersAtom.useLoading();
  const data = usersAtom.useData();
  const error = usersAtom.useError();
  if (isLoading) return <Spinner />;
  if (error) return <p className="text-red-500">{String(error)}</p>;
  return <ul>{data?.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}
```

For richer caching/invalidation, use [`@mongez/atomic-query`](https://github.com/hassanzohdy/mongez-atomic-query) instead.

## Granular subscriptions on object atoms

```ts
const profile = atom({
  key: "profile",
  default: { name: "Anon", email: "", lastSeen: 0 },
});

// Only re-renders when `name` changes.
function NameDisplay() {
  const name = profile.use("name");
  return <span>{name}</span>;
}

// Updating `lastSeen` does NOT re-render `NameDisplay`.
setInterval(() => profile.change("lastSeen", Date.now()), 1000);
```

## SSR snapshot/hydrate (Next.js)

```tsx
// app/layout.tsx (server component)
import { createAtomStore } from "@mongez/atom";
import { AtomStoreProvider, HydrateAtomsScript } from "@mongez/react-atom";
import { userAtom } from "@/state/user";

export default function Layout({ children, currentUser }) {
  const store = createAtomStore();
  store.use(userAtom).update(currentUser);
  return (
    <AtomStoreProvider store={store}>
      {children}
      <HydrateAtomsScript snapshot={store.snapshot()} />
    </AtomStoreProvider>
  );
}
```

```tsx
// app/client-root.tsx
"use client";
import { AtomStoreProvider, readHydration } from "@mongez/react-atom";

export function ClientRoot({ children }) {
  return (
    <AtomStoreProvider initialValues={readHydration() ?? undefined}>
      {children}
    </AtomStoreProvider>
  );
}
```

## Action method from an event handler (SSR-safe)

```tsx
import { useAtom } from "@mongez/react-atom";

function LogoutButton() {
  const auth = useAtom(authAtom);   // store-scoped under a provider
  return <button onClick={() => auth.logout()}>Log out</button>;
}
```

Without `useAtom(authAtom)`, calling `authAtom.logout()` would mutate the module-level template — fine on the client, wrong on the server.

## Atom for an external library's state

`<atom.Provider>` is useful when an external library hands you state that you want to mirror into an atom.

```tsx
const themeAtom = atom({ key: "theme", default: "light" as "light" | "dark" });

function App({ themeFromOS }) {
  return (
    <themeAtom.Provider value={themeFromOS}>
      <RestOfApp />
    </themeAtom.Provider>
  );
}
```

## Devtools in a React dev build

```ts
// app entry
import { enableAtomDevtools } from "@mongez/atom";

if (process.env.NODE_ENV !== "production") {
  enableAtomDevtools({ name: "MyReactApp" });
}
```

Connects to Redux DevTools — every atom (including `fetchingAtom`s and `portalAtom`s) appears in the timeline.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.