Skip to content

Preset atoms

Four pre-built atom shapes that collapse common patterns to one line.

openAtom

A boolean-shaped toggle with open, close, toggle, and a useOpened() hook.

import { openAtom } from "@mongez/react-atom";
const sidebar = openAtom("sidebar", /* defaultOpened */ false);
// Anywhere:
sidebar.open();
sidebar.close();
sidebar.toggle();
// In components:
function Sidebar() {
const opened = sidebar.useOpened();
return opened ? <Drawer /> : null;
}

Equivalent to writing:

const sidebar = atom<boolean, { open(): void; close(): void; toggle(): void; useOpened(): boolean }>({
key: "sidebar",
default: false,
actions: {
open() { this.update(true); },
close() { this.update(false); },
toggle() { this.update(!this.value); },
useOpened() { return (this as any).useValue(); },
},
});

loadingAtom

A boolean with startLoading / stopLoading / toggleLoading verbs.

import { loadingAtom } from "@mongez/react-atom";
const usersLoading = loadingAtom("usersLoading");
async function fetchUsers() {
usersLoading.startLoading();
try {
const users = await api.users.list();
setUsers(users);
} finally {
usersLoading.stopLoading();
}
}

fetchingAtom

A full fetch lifecycle: isLoading, data, error, optional pagination. Comes with startLoading, stopLoading, success(data, pagination?), failed(error), append(data), prepend(data), plus hooks useLoading(), useData(), useError(), usePagination().

import { fetchingAtom } from "@mongez/react-atom";
type User = { id: number; name: string };
const usersAtom = fetchingAtom<User[]>("users");
async function loadUsers() {
usersAtom.startLoading();
try {
const { data, pagination } = await api.users.list();
usersAtom.success(data, pagination);
} 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 <ErrorBox e={error} />;
return <ul>{data?.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

For richer cache management, prefer @mongez/atomic-query. fetchingAtom is for one-off fetch flows; queryAtom.useQuery is for keyed cache.

portalAtom

A coordinator atom for modals, drawers, tooltips, dropdowns. Holds { opened: boolean, data: T } and exposes open(data?), close(), toggle(data?), useOpened(), useData().

import { portalAtom } from "@mongez/react-atom";
type DeleteData = { userId: number; userName: string };
const deleteUserModal = portalAtom<DeleteData>("deleteUserModal");
// Anywhere:
deleteUserModal.open({ userId: 7, userName: "Alice" });
function ConfirmDeleteUser() {
const opened = deleteUserModal.useOpened();
const { userId, userName } = deleteUserModal.useData();
if (!opened) return null;
return (
<Dialog>
<p>Delete {userName}?</p>
<button onClick={() => deleteUserModal.close()}>Cancel</button>
<button onClick={async () => { await api.users.remove(userId); deleteUserModal.close(); }}>
Delete
</button>
</Dialog>
);
}

Each portalAtom key is suffixed with -portal internally, so portalAtom("deleteUser") creates an atom whose key is deleteUser-portal.