Patterns e convencoes para projetos Next.js com React
Referencia de patterns e convencoes para projetos Next.js + React.
src/app/
├── layout.tsx # Root layout (Server Component)
├── page.tsx # Home page
├── loading.tsx # Loading UI
├── error.tsx # Error boundary (Client Component)
├── not-found.tsx # 404 page
├── (auth)/ # Route group
│ ├── login/page.tsx
│ └── register/page.tsx
├── dashboard/
│ ├── layout.tsx # Nested layout
│ └── [id]/page.tsx # Dynamic route
└── api/
└── route.ts # API route handler
| Criterio | Server Component | Client Component |
|---|---|---|
| Default | Sim (padrao) | Precisa 'use client' |
| Fetch data | Sim (async/await) | Via hooks |
| useState/useEffect | Nao | Sim |
| Event handlers | Nao | Sim |
| Bundle size | Nao inclui | Inclui no bundle |
Regra: Comece como Server Component. Adicione 'use client' apenas quando precisar de interatividade.
export default async function UsersPage() {
const users = await getUsers();
return <UserList users={users} />;
}
export default async function Page() {
const data = await fetchData();
return (
<div>
<h1>Server rendered</h1>
<InteractiveWidget initialData={data} />
</div>
);
}
export function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const timer = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timer);
}, [value, delay]);
return debouncedValue;
}
'use client';
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>Algo deu errado</h2>
<button onClick={reset}>Tentar novamente</button>
</div>
);
}
sm:, md:, lg:, xl:)dark: prefixhover:, focus:, focus-visible:next/image com width e heightnext/fontnext/dynamic para lazy loadinguseMemo/useCallback apenas quando necessario