Пошук уроків, статей та іншого контенту
Async-компоненти замість useEffect, поведінка кешування fetch та як уникнути waterfall-запитів.
У React SPA типовий патерн для завантаження даних — useState для даних і статусу завантаження плюс useEffect, що виконує запит після монтування компонента. У Server Component цього не потрібно: компонент сам може бути async-функцією, яка напряму await-ить дані ще до того, як щось відправиться клієнту — жодного «спалаху» порожнього стану чи спінера на першому рендері.
// Server Component — дані вже готові на момент рендеру, спінер не потрібен
async function PostsPage() {
const posts = await getPosts(); // пряме звернення до бази даних чи fetch
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}У ранніх версіях App Router (Next.js 13–14) виклики fetch() кешувались автоматично за замовчуванням. Починаючи з Next.js 15 це змінено на протилежне: fetch() за замовчуванням не кешується — кожен виклик отримує свіжі дані, а кешування потрібно вмикати явно. Багато туторіалів в інтернеті ще описують стару поведінку — орієнтуйтесь на офіційну документацію конкретної версії.
// Явне кешування (Next.js 15+): дані кешуються, поки не мине revalidate
const res = await fetch("https://api.example.com/posts", {
next: { revalidate: 3600 },
});
// Без опцій — свіжий запит щоразу (поведінка за замовчуванням у Next.js 15+)
const res = await fetch("https://api.example.com/posts");Послідовні await-запити, що не залежать один від одного, змушують чекати кожен по черзі — типова помилка, знайома з основного курсу JavaScript (стаття «N+1 Query Problem» розбирає той самий принцип на прикладі бази даних). У Server Components та сама проблема виникає з незалежними джерелами даних:
// Повільно: другий запит чекає завершення першого, хоча не залежить від нього
const user = await getUser(userId);
const posts = await getPostsByUser(userId);
// Швидко: обидва запити виконуються одночасно
const [user, posts] = await Promise.all([
getUser(userId),
getPostsByUser(userId),
]);Використовувати useEffect + useState для початкового завантаження даних у Server Component — там, де компонент може просто бути async-функцією й await-ити дані напряму, без клієнтського хука.
Розраховувати на автоматичне кешування fetch() за поведінкою старих версій Next.js — з 15 версії кешування потрібно вмикати явно опцією next.revalidate чи cache: 'force-cache'.
Послідовні await для незалежних джерел даних замість Promise.all — кожен зайвий послідовний запит додає латентність до часу відповіді всієї сторінки.
Server Components отримують дані напряму — async-функція компонента await-ить fetch чи звернення до бази даних без useEffect/useState. Починаючи з Next.js 15, fetch() за замовчуванням НЕ кешується (зміна порівняно з попередніми версіями) — кешування вмикається явно. Незалежні запити варто запускати паралельно через Promise.all, а не послідовними await, щоб уникнути зайвої латентності.