Rendering Patterns 🎭
Rendering logic is storytelling—decide which scenes (components) appear based on data. These patterns keep your Next.js components tidy.
Lists 🔁
const features = [
{ id: 'fast', title: 'Blazing Fast' },
{ id: 'secure', title: 'Secured' },
];
<ul>
{features.map(feature => (
<li key={feature.id}>{feature.title}</li>
))}
</ul>- Provide stable
keyprops (ids, not array indices unless static). - Extract list items into components for readability.
Conditional Rendering ⚖️
{isLoading ? <Spinner /> : <DataTable rows={rows} />}Common idioms:
- Ternary (
cond ? A : B) for mutually exclusive blocks. - Logical AND:
{isAdmin && <AdminPanel />}. - Early returns in functions to avoid nested JSX.
Guard Components 🛂
Encapsulate conditions in wrapper components.
function AuthGate({ isAuthed, children }) {
if (!isAuthed) return <LoginPrompt />;
return <>{children}</>;
}Skeletons & Placeholders 🦴
- Show skeleton UI while data loads, then swap to content.
- Next.js
Suspenseboundaries +loading.tsxsimplify this pattern.
Empty States 🫙
- Always render a meaningful fallback for empty arrays or missing data.
- Example:
{items.length === 0 ? <EmptyState /> : <ItemGrid items={items} />}.
Server vs Client Rendering 🧠
- Server components can branch before sending HTML (cheap).
- Client components might need guards for browser-only APIs (
typeof window !== 'undefined').
Analogy: rendering patterns are stage cues—lights (conditions) determine which actors (components) step forward.
Plan list keys, empty states, and loading fallbacks upfront for polished UX. ✨
Last updated on