How this works
A "custom hook" — a function whose name starts with use that internally calls other hooks. useStore subscribe" class="text-blue-700 underline decoration-blue-200 underline-offset-2 hover:decoration-blue-500">subscribes the calling component to the cart atom; useMemo recomputes items / subtotal / count only when the underlying $cart changes. Returning a frozen object keeps consumers from re-rendering on shape mutations.
import { useMemo } from 'react';
import { useStore } from '@nanostores/react';
import { cart, type CartItem } from '../stores/cart';
export type CartTotals = {
items: CartItem[];
subtotal: number;
count: number;
};
/**
* Custom hook: subscribes to the cart store and returns the items list,
* subtotal, and total quantity. The useMemo guards against re-allocating
* the totals object on unrelated re-renders.
*/
export function useCart(): CartTotals {
const $cart = useStore(cart);
return useMemo(() => {
const items = Object.values($cart);
const subtotal = items.reduce((s, i) => s + i.price * i.qty, 0);
const count = items.reduce((s, i) => s + i.qty, 0);
return { items, subtotal, count };
}, [$cart]);
}