Irbisa · Шпаргалка
Server Components и Next.js
React Server Components, серверные функции, CSR, SSR, SSG и ISR, стриминг, ошибки гидратации, App Router в Next.js, кэширование
Что такое React Server Components и чем они отличаются от клиентских компонентов?
// app/posts/[id]/page.tsx: a Server Componentexport default async function PostPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const post = await db.post.findUnique({ where: { id } }); if (!post) notFound();…Чем отличаются CSR, SSR, SSG и ISR и когда выбирать каждый вариант?
Как устроены файловые соглашения App Router:
page,layout,loading,errorиnot-found?// app/dashboard/error.tsx'use client'; export default function DashboardError({ error, reset,…Что на самом деле помечает
"use client"и где ставить эту границу?// app/products/page.tsx: Server Componentexport default async function ProductsPage() { const products = await getProducts(); return ( <FilterPanel> {/* rendered on the server, passed through the client boundary */}…Что серверный компонент может передать клиентскому в пропсах, а что вызовет ошибку?
// app/posts/[id]/page.tsx: Server Componentexport default async function PostPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const commentsPromise = getComments(id); // not awaited: the page streams on return ( <Suspense fallback={<p>Loading comments...</p>}>…Найдите баг: страница падает с ошибкой «Event handlers cannot be passed to Client Component props.»
// app/cart/page.tsxexport default async function CartPage() { const cart = await getCart(); return ( <div> <p>{cart.items.length} items</p> <button onClick={() => console.log('checkout', cart.id)}> Checkout </button> </div> );}Как в приложении на Server Components не допустить попадания секретов и серверного кода в клиентский бандл?
// lib/data/users.tsimport 'server-only'; export async function getProfile(userId: string) { const user = await db.user.findUnique({ where: { id: userId } }); if (!user) return null;…Что такое Server Functions (Server Actions) и как вызвать такую функцию из формы?
// app/todos/actions.ts'use server'; export async function createTodo( _prev: { error?: string }, formData: FormData,…Что такое Route Handlers (
route.ts) в App Router, и когда использовать их вместо Server Action?// app/api/webhooks/payments/route.ts: called by the payment provider, not by your UIexport async function POST(request: Request) { const body = await request.text(); // the raw body: the signature is computed over it const signature = request.headers.get('x-signature') ?? ''; if (!(await verifySignature(body, signature, process.env.PAYMENTS_WEBHOOK_SECRET!))) { return new Response('Invalid signature', { status: 400 });…Что делает
proxy.ts(бывшийmiddleware.ts) в Next.js 16, и что в него не стоит класть?// proxy.ts (Next.js 16; formerly middleware.ts with `export function middleware`)import { NextResponse, type NextRequest } from 'next/server'; export function proxy(request: NextRequest) { // optimistic check: no cookie means no session, so do not even render the page if (request.nextUrl.pathname.startsWith('/account') && !request.cookies.has('session')) {…Как загружать данные в серверных компонентах и как избежать водопада запросов?
export default async function DashboardPage() { // both requests start before either is awaited const [user, orders] = await Promise.all([getUser(), getOrders()]); return ( <>…Как работает потоковый SSR (streaming) с
Suspenseиloading.tsx?// app/product/[id]/page.tsxexport default async function ProductPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const product = await getProduct(id); // fast: part of the first chunk return (…Что вызывает ошибку несовпадения при гидратации (hydration mismatch) и как её исправить?
Найдите баг: кнопка темы выдаёт ошибку гидратации, но только у пользователей, выбравших тёмную тему.
// ThemeToggle.tsx'use client'; export function ThemeToggle() { const saved = typeof window !== 'undefined' ? localStorage.getItem('theme') : null; const [theme, setTheme] = useState(saved ?? 'light'); return ( <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}> {theme === 'dark' ? 'Light mode' : 'Dark mode'} </button> );}Когда вы выберете клиентское SPA (Vite и React Router), а не Next.js с серверными компонентами?
Как настроить SEO в App Router из Next.js:
metadata,generateMetadata,sitemap.tsи канонические адреса страниц?// app/layout.tsxexport const metadata: Metadata = { metadataBase: new URL('https://shop.example'), title: { template: '%s | Shop', default: 'Shop' },};…Почему каждый Server Action по сути публичный эндпоинт и как его защитить?
// app/posts/actions.ts'use server'; const RenameInput = z.object({ postId: z.string().min(1), title: z.string().min(1).max(200) }); export async function renamePost(formData: FormData) {…Как устроено кэширование в Next.js App Router и что изменилось в Next.js 15 и 16?
import { cacheLife, cacheTag } from 'next/cache'; export async function getProducts(category: string) { 'use cache'; cacheLife('hours'); cacheTag('products', `products-${category}`);…Как после мутации заставить App Router показать свежие данные:
revalidatePath,revalidateTag,updateTagилиrouter.refresh?'use server'; import { revalidateTag, updateTag } from 'next/cache'; export async function publishPost(postId: string) { await requireEditor();…Что делает
cache()из React в серверных компонентах и чем он отличается от"use cache"в Next.js?import { cache } from 'react'; export const getUser = cache(async (id: string) => { return db.user.findUnique({ where: { id } });});…Найдите баг: после деплоя пользователи иногда видят в шапке страницы имя другого пользователя.
// lib/current-user.tslet currentUser: User | null = null; // the layout, the header and the page all call it: query the database only onceexport async function getCurrentUser() { if (!currentUser) { const session = await auth(); currentUser = await db.user.findUnique({ where: { id: session.userId } }); } return currentUser;} // app/Header.tsxexport async function Header() { const user = await getCurrentUser(); return <p>Signed in as {user?.name}</p>;}Что сервер отправляет для серверных компонентов (RSC payload) и как клиент использует это при навигации?