ae39e45460
NOVAS SKILLS: - next-best-practices v0.1.0 (CLEAN) — Next.js App Router, RSC, caching, data - nextjs-patterns v1.0.0 (CLEAN) — Next.js 15: Server Actions, route handlers - vite v1.0.0 (CLEAN) — env vars, aliases, proxy, CJS compat - uncle-bob v1.0.0 (CLEAN) — Clean Code, SOLID, Clean Architecture - clean-code-review v1.0.0 (CLEAN) — naming, guard clauses, anti-patterns, refactoring - vue v1.0.0 (CLEAN) — Vue framework - vue-composition-api-best-practices v1.0.0 (CLEAN) — composables, Pinia, reactivity BIBLIOTECA INTELIGENTE libs/ (10 dominios, 11 arquivos): - typescript/ — TS safe + generics gotchas - react/ — Next.js App Router + Vite config - vue/ — Composition API + Pinia - linux/ — System diagnostic cheatsheet - database/ — PostgreSQL + MySQL patterns - browser/ — Chromium CLI + E2E testing - security/ — SAST audit (OWASP Top 10) - best-practices/ — Clean Code + SOLID + Clean Architecture - deploy/ — Docker multi-stack + OpenClaw ops - + INDEX.md como guia de navegacao .learnings/ — LRN-20260519-003 criado (biblioteca compartilhada)
88 lines
1.6 KiB
Markdown
88 lines
1.6 KiB
Markdown
# Async Patterns
|
|
|
|
In Next.js 15+, `params`, `searchParams`, `cookies()`, and `headers()` are asynchronous.
|
|
|
|
## Async Params and SearchParams
|
|
|
|
Always type them as `Promise<...>` and await them.
|
|
|
|
### Pages and Layouts
|
|
|
|
```tsx
|
|
type Props = { params: Promise<{ slug: string }> }
|
|
|
|
export default async function Page({ params }: Props) {
|
|
const { slug } = await params
|
|
}
|
|
```
|
|
|
|
### Route Handlers
|
|
|
|
```tsx
|
|
export async function GET(
|
|
request: Request,
|
|
{ params }: { params: Promise<{ id: string }> }
|
|
) {
|
|
const { id } = await params
|
|
}
|
|
```
|
|
|
|
### SearchParams
|
|
|
|
```tsx
|
|
type Props = {
|
|
params: Promise<{ slug: string }>
|
|
searchParams: Promise<{ query?: string }>
|
|
}
|
|
|
|
export default async function Page({ params, searchParams }: Props) {
|
|
const { slug } = await params
|
|
const { query } = await searchParams
|
|
}
|
|
```
|
|
|
|
### Synchronous Components
|
|
|
|
Use `React.use()` for non-async components:
|
|
|
|
```tsx
|
|
import { use } from 'react'
|
|
|
|
type Props = { params: Promise<{ slug: string }> }
|
|
|
|
export default function Page({ params }: Props) {
|
|
const { slug } = use(params)
|
|
}
|
|
```
|
|
|
|
### generateMetadata
|
|
|
|
```tsx
|
|
type Props = { params: Promise<{ slug: string }> }
|
|
|
|
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
|
const { slug } = await params
|
|
return { title: slug }
|
|
}
|
|
```
|
|
|
|
## Async Cookies and Headers
|
|
|
|
```tsx
|
|
import { cookies, headers } from 'next/headers'
|
|
|
|
export default async function Page() {
|
|
const cookieStore = await cookies()
|
|
const headersList = await headers()
|
|
|
|
const theme = cookieStore.get('theme')
|
|
const userAgent = headersList.get('user-agent')
|
|
}
|
|
```
|
|
|
|
## Migration Codemod
|
|
|
|
```bash
|
|
npx @next/codemod@latest next-async-request-api .
|
|
```
|