React Patterns
Modern React and Next.js patterns with TypeScript.
Framework Selection
| Setup | Best For | Use When | |-------|----------|----------| | Next.js App Router | Full-stack, SSR/SSG | SEO matters, need server components | | Next.js Pages Router | Simpler SSR | Legacy project, simpler mental model | | Vite + React | SPA, client-only | No SSR needed, fastest dev experience | | Create React App | Legacy | Avoid for new projects |
Reference Files
| Topic | Load | Use When | |-------|------|----------| | Project structure | references/project-structure.md | Setting up or organizing code | | Components | references/components.md | Building UI components | | State management | references/state-management.md | Managing app/component state | | Data fetching | references/data-fetching.md | API calls, server data | | Forms | references/forms.md | Form handling and validation | | Auth (client) | references/auth-client.md | Client-side authentication |
Quick Start Patterns
Next.js App Router Page
// app/users/page.tsx
import { getUsers } from '@/lib/api';
import { UserList } from '@/components/users/UserList';
export default async function UsersPage() {
const users = await getUsers();
return (
<main className="container mx-auto py-8">
<h1 className="text-2xl font-bold mb-6">Users</h1>
<UserList users={users} />
</main>
);
}
Client Component
'use client';
import { useState } from 'react';
interface CounterProps {
initialCount?: number;
}
export function Counter({ initialCount = 0 }: CounterProps) {
const [count, setCount] = useState(initialCount);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
}
API Route (App Router)
// app/api/users/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
const users = await db.user.findMany();
return NextResponse.json(users);
}
export async function POST(request: Request) {
const body = await request.json();
const user = await db.user.create({ data: body });
return NextResponse.json(user, { status: 201 });
}
Essential Packages
| Package | Purpose | |---------|---------| | typescript | Type safety | | tailwindcss | Styling | | @tanstack/react-query | Server state | | zustand | Client state | | react-hook-form | Forms | | zod | Validation | | framer-motion | Animations | | lucide-react | Icons |
TypeScript Rules
- Explicit prop types - Interface for every component
- No
any- Useunknownif needed - Strict mode - Enable in tsconfig
- Type imports - Use
import typewhen possible
Code Quality Rules
- Functional components - No class components
- Named exports - Except page defaults
- Small files - One component per file
- Custom hooks - Extract reusable logic
- Error boundaries - Wrap key sections
- Loading states - Always handle loading/error