یکی از جذابترین ویژگیهای معماری مدرن Next.js این است که به شما اجازه میدهد دادههای خود را مستقیماً درون کامپوننتهای سروری دریافت (Fetch) کنید. از آنجا که این کدها صرفاً روی سرور آپلود و اجرا میشوند، شما محدودیتی در استفاده از ابزارهای ناهمگام (Asynchronous I/O) ندارید.
شما میتوانید به دو روش اصلی دیتای خود را تامین کنید:
-
استفاده از متد بومی
fetchAPI -
اتصال مستقیم به دیتابیس از طریق یک ORM (مثل Prisma یا Drizzle) یا کلاینتِ دیتابیس.
چیزهایی که در این درس یاد میگیرید:
-
نحوه تبدیل کامپوننت به یک تابع
asyncبرای دریافت دیتا -
مکانیزم بهینهسازی
Memoizationدر درخواستهای مشابه -
دوری از بلاک شدن صفحه در زمان لود دیتا به کمک
<Suspense> -
کوئری زدن مستقیم و امن به دیتابیس بدون نیاز به ساخت API Route مجزا
۱. دریافت داده با استفاده از fetch API
برای دریافت اطلاعات از یک API خارجی، کافی است کامپوننت خود را به یک تابع ناهمگام (async function) تبدیل کرده و پشت متد fetch از کلمه کلیدی await استفاده کنید:
// app/blog/page.tsx
export default async function Page() {
// ۱. ارسال درخواست به API و انتظار برای پاسخ سرور
const data = await fetch('https://api.vercel.app/blog')
const posts = await data.json()
// ۲. رندر خروجی به صورت کاملاً آماده در سمت سرور
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
سه نکته حیاتی که باید بدانید (Good to know):
-
مفهوم Memoization (بهخاطرسپاری خودکار): اگر در جاهای مختلفی از درخت کامپوننتهای خود (مثلاً در هدر، سایدبار و صفحه اصلی) نیاز به یک دیتای مشترک از یک آدرس
fetchیکسان داشته باشید، ریاکت به صورت خودکار آن درخواست را دیدوپلیکیت (Deduplicate) میکند. یعنی فقط یکبار درخواست را به سرور مقصد میفرستد و بقیه جاها از کشِ همان رندر استفاده میکنند. پس نیازی به پاس دادن طولانی دیتا از والد به فرزند (Props Drilling) ندارید! -
درخواستها رندر را بلاک میکنند: متد
fetchبه صورت پیشفرض کَش نمیشود و تا زمانی که پاسخ خود را کامل از اینترنت دریافت نکند، اجازه رندر شدن و نمایش صفحه را به کاربر نمیدهد. برای حل این مشکل دو راه دارید: یا از دایرکتیو جدیدuse cacheبرای ذخیره پاسخ استفاده کنید، یا کامپوننت دریافتکننده دیتا را درون یک تگ<Suspense>کلاینتی بپیچید تا سیستم بتواند کدهای صفحه را به صورت استریم (Streaming) و قطرهچکانی به مرورگر بفرستد. -
لاگگیری کدهای شبکه: در محیط توسعه (Development)، میتوانید لاگهای مربوط به فراخوانیهای
fetchرا در ترمینال فعال کنید تا متوجه شوید چه درخواستی در چه زمانی به سرور فرستاده میشود.
۲. اتصال مستقیم به دیتابیس با ORM یا Database Client
از آنجا که این کامپوننتها به هیچ عنوان سر از مرورگر کاربر در نمیآورند، جاوااسکریپت آنها به کلاینت فرستاده نشده و در نتیجه تمام اطلاعات حساس پروژه (مثل کلمات عبور دیتابیس، امضای کوئریها و منطقهای SQL) کاملاً پنهان و امن باقی میمانند.
بنابراین، شما میتوانید بدون نیاز به ساختن یک API Route واسط، مستقیماً دیتابیس خود را در همان فایل صفحه صدا بزنید:
// app/blog/page.tsx
import { db, posts } from '@/lib/db' // ایمپورت کلاینت دیتابیس یا ORM پروژه
export default async function Page() {
// کوئری زدن مستقیم به دیتابیس روی سرور خودمان!
const allPosts = await db.select().from(posts)
return (
<ul>
{allPosts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
⚠️ یک تذکر امنیتی مهم: اتصال مستقیم به دیتابیس دست شما را برای کوئری زدن بسیار باز میگذارد، اما همیشه باید مطمئن شوید که درخواستهای ورودی به درستی احراز هویت (Authentication) و اعتبارسنجی سطح دسترسی (Authorization) شده باشند تا کاربری نتواند به دیتای کاربران دیگر دسترسی پیدا کند.
خلاصه عملکرد (Recap)
-
کامپوننتهای سروری را با چسباندن کلمه کلیدی
asyncآماده دریافت مستقیم دیتا کنید. -
متد
fetchدرخواستهای کاملاً همشکل را در یک دور رندر پاکسازی (Memoize) میکند تا از تکرار بیهوده جلوگیری شود. -
برای جلوگیری از معطل شدن کاربر پشت لودینگهای سنگین شبکه، از ابزار استریمینگ مانند
<Suspense>استفاده کنید. -
با خیال راحت و امنیت صددرصدی، کوئریهای خود را مستقیماً با ORM درون فایل کامپوننت بنویسید و دیتابیس را شخم بزنید!
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: منبع مستندات