Hooks
Memoize classmate components when you need to declare them inside another React component.
useClassmate keeps a stable component reference between renders. Reach for the hook whenever you have to create a classmate component inside another component (for example because the builder depends on React state, context or hooks). Without memoization every render would create a brand-new component tree which makes React re-mount your component and can lead to hydration mismatches.
Wrap the factory with useClassmate and return the memoized component. All props still work the same way and you can forward $-prefixed values for dynamic interpolations.
import rc, { useClassmate } from "react-classmate"
type DayStatus = "completed" | "pending"
export const WorkoutDay = ({ label, status }: { label: string; status: DayStatus }) => {
const StyledDay = useClassmate(
() =>
rc.div<{ $status: DayStatus }>`
rounded-md border p-4 text-sm font-medium transition-colors
${(p) => (p.$status === "completed" ? "bg-green-50 border-green-500 text-green-900" : "")}
${(p) => (p.$status === "pending" ? "bg-slate-50 border-slate-300 text-slate-900" : "")}
`,
[],
)
return (
<StyledDay $status={status}>
{label}: {status}
</StyledDay>
)
}
Pass a dependency array as the second argument. It behaves the same as React.useMemo: the classmate component is only re-created when one of the dependencies changes. This enables things like theme-aware builders or locale-specific layout tweaks without re-instantiating on every render.
import rc, { useClassmate } from "react-classmate"
type Tone = "primary" | "secondary"
interface InsightCardProps {
tone: Tone
headline: string
description: string
}
export const InsightCard = ({ tone, headline, description }: InsightCardProps) => {
const Card = useClassmate(
() =>
rc.article`
p-6 rounded-xl border transition-all duration-200 shadow-sm
${tone === "primary" ? "bg-primary/5 border-primary/50" : "bg-slate-900 border-slate-800 text-white"}
`,
[tone],
)
return (
<Card aria-label={`${tone} insight`}>
<h3 className="text-base font-semibold mb-1">{headline}</h3>
<p className="text-sm opacity-80">{description}</p>
</Card>
)
}
Keep the dependency array in sync with the values captured inside the factory. Forgetting a dependency will freeze the previous classes because the memoized component never re-computes.
rc.extend; the hook just guarantees that React sees a stable component identity.useClassmate with the new .logic() helper if you need derived props and memoization at the same time.