«در Next.js 13 به بعد، ما با دو نوع کامپوننت مواجه هستیم: Server Components و Client Components. این معماری به ما اجازه میدهد بهترین عملکرد را داشته باشیم: سرعت بالا، امنیت بهتر، و تجربه کاربری روان. نکته کلیدی این است که همه کامپوننتها به صورت پیشفرض Server هستند و فقط وقتی نیاز به تعامل داریم، با
'use client'آنها را به Client تبدیل میکنیم.»
«کامپوننتهایی که روی سرور رندر میشوند و خروجی HTML به مرورگر فرستاده میشود. اینها پیشفرض Next.js هستند و نیازی به نشانهگذاری خاصی ندارند.»
سرعت بارگذاری: چون کد جاوااسکریپت کمتری به مرورگر میرود، صفحه سریعتر لود میشود
SEO بهتر: موتورهای جستجو محتوای کامل HTML را میبینند
دسترسی مستقیم به دیتابیس: بدون نیاز به API، مستقیماً با دیتابیس ارتباط برقرار میکنند
امنیت بیشتر: کدهای حساس مثل توکنها و کلیدهای API هرگز به کلاینت نمیروند
«فرض کنید لیست محصولات را از دیتابیس میخوانیم. این کار را در Server Component انجام میدهیم چون نیازی نیست کاربر منتظر بارگذاری جاوااسکریپت بماند و اطلاعات مستقیم از سرور میآید.»
javascript
// ✅ Server Component (پیشفرض) export default async function ProductList() { const products = await db.products.findMany(); return ( <div> {products.map(p => <ProductCard key={p.id} {...p} />)} </div> ); }
«کامپوننتهایی که با
'use client'مشخص میشوند و روی مرورگر اجرا میشوند. اینها برای تعاملات کاربری ضروری هستند.»
تعاملات کاربری: کلیک، hover، تغییر state
استفاده از Hookهای React:
useState،useEffect،useContextAPIهای مرورگر:
localStorage،window،document
«فرم افزودن تسک که کاربر در آن تایپ میکند و دکمه میزند، باید Client Component باشد.»
javascript
'use client'; // ✅ Client Component import { useState } from 'react'; export default function AddTodoForm() { const [title, setTitle] = useState(''); return ( <input value={title} ={(e) => setTitle(e.target.value)} /> ); }
'use server')«توابعی که با
'use server'علامتگذاری میشوند و فقط روی سرور اجرا میشوند، اما میتوان آنها را از Client Components صدا زد.»
عملیات امن: ثبتنام، ورود، آپدیت دیتابیس
جایگزین API: بدون نیاز به نوشتن REST API یا GraphQL
مدیریت داده: افزودن، ویرایش، حذف اطلاعات
«وقتی کاربر فرم ثبتنام را پر میکند، به جای ارسال به API عمومی، یک Server Action صدا میزنیم که مستقیماً با دیتابیس ارتباط برقرار میکند.»
javascript
'use server'; // ✅ Server Action export async function addTodo(formData) { const title = formData.get('title'); await db.todo.create({ data: { title } }); revalidatePath('/'); // بازسازی صفحه return { success: true }; }

«برای مدیریت فرمها در Next.js، سه روش داریم که هر کدام کاربرد خاص خود را دارند:»
«برای فرمهای ساده با یک دکمه Submit، از هوکهای
useFormStatusوuseFormStateاستفاده میکنیم. این روش خودکار loading و error را مدیریت میکند.»
javascript
'use client'; import { useFormState, useFormStatus } from 'react-dom'; function SubmitButton() { const { pending } = useFormStatus(); // ✅ خودکار return <button disabled={pending}>ارسال</button>; } function Form() { const [state, formAction] = useFormState(addTodo, initialState); return ( <form action={formAction}> <input name="title" /> <SubmitButton /> {state?.error && <p>{state.error}</p>} </form> ); }
«برای عملیاتهای پیچیدهتر مثل چندین دکمه مختلف در یک صفحه، یا عملیات دستهای، از
useTransitionاستفاده میکنیم. این روش کنترل کامل روی loading و error میدهد و اجازه میدهد چندین عملیات مجزا داشته باشیم.»
javascript
'use client'; import { useTransition } from 'react'; function BulkActions() { const [isDeleting, startDelete] = useTransition(); const [isCompleting, startComplete] = useTransition(); return ( <> <button ={() => startDelete(deleteAll)} disabled={isDeleting}> {isDeleting ? 'در حال حذف...' : 'حذف همه'} </button> <button ={() => startComplete(completeAll)} disabled={isCompleting}> {isCompleting ? 'در حال تکمیل...' : 'تکمیل همه'} </button> </> ); }
سناریوروش مناسبفرم ثبتنام سادهuseFormStatus + useFormStateفرم با چندین دکمه مختلفuseTransitionعملیات دستهای (حذف گروهی)useTransitionناوبری بین صفحاتuseTransition + useRouterآپدیتهای سنگین UIuseTransitionفرم با اعتبارسنجی پیچیدهuseFormState + اعتبارسنجی در Server Action
«۵ اصل مهم که همیشه رعایت میکنم:»
تا جایی که ممکن است از Server Components استفاده کنید و فقط بخشهای تعاملی را Client کنید
دادههای حساس را در Server Actions نگهداری کنید، نه در Client Components
برای فرمهای ساده از useFormStatus و useFormState و برای عملیات پیچیده از useTransition استفاده کنید
از revalidatePath یا revalidateTag بعد از هر تغییر داده استفاده کنید تا صفحه آپدیت شود
همیشه اعتبارسنجی را در Server Action انجام دهید، حتی اگر در کلاینت هم انجام میدهید (امنیت)
«در Next.js مدرن، استراتژی من این است: همه چیز را Server Component شروع میکنم. اگر به تعامل کاربری نیاز داشت، با
'use client'آن بخش را به Client تبدیل میکنم. برای عملیاتهای امن روی داده، از'use server'استفاده میکنم. برای مدیریت فرمها، اگر ساده است ازuseFormStatusوuseFormStateو اگر پیچیده است ازuseTransitionاستفاده میکنم. این رویکرد به من میدهد: سرعت بالا، امنیت عالی، و تجربه کاربری روان، بدون اینکه مجبور باشم بین SSR و SPA یکی را انتخاب کنم.»
«برای ترکیب بهترینهای SSR (سرعت و SEO) با SPA (تعامل پذیری). با این روش، میتوانیم هم صفحات سریع داشته باشیم و هم اپلیکیشنهای پویا و تعاملی بسازیم، بدون اینکه مجبور باشیم یکی را فدا کنیم.»
«خیر. اگر یک کامپوننت را
'use client'کنیم، تمام زیرکامپوننتهای آن هم Client میشوند، مگر اینکه به صورتchildrenیاpropاز بالا ارسال شوند. بهترین روش این است که کامپوننتهای تعاملی را در لایههای بالایی قرار دهیم و دادهها را از Server Components به آنها پاس دهیم.»
«با
useFormStateخطاها به صورت خودکار مدیریت میشوند. باuseTransitionازtry/catchاستفاده میکنیم. همچنین میتوانیم ازerror.tsxدر Next.js برای نمایش خطاهای سرور استفاده کنیم.»
useTransition به جای useFormStatus استفاده کنیم؟"«
useFormStatusفقط در فرمهای ساده با یک دکمه Submit کار میکند. اما اگر چندین دکمه در یک صفحه داریم (مثل حذف گروهی، تکمیل گروهی، فیلتر کردن) یا میخواهیم ناوبری نرم داشته باشیم، ازuseTransitionاستفاده میکنیم که کنترل بیشتری به ما میدهد.»
مفهومیک خط توضیحServer Componentرندر روی سرور، پیشفرض، بدون 'use client'Client Componentرندر روی مرورگر، برای تعامل، با 'use client'Server Actionاجرا روی سرور، با 'use server'، برای عملیات امنuseFormStatusمدیریت خودکار loading در فرمهای سادهuseFormStateمدیریت خودکار state و error در فرمهاuseTransitionمدیریت عملیات غیرهمزمان پیچیده و چندگانه
نکته نهایی برای مصاحبه:
«با این رویکرد، من نه تنها کد تمیز و مدرن مینویسم، بلکه اپلیکیشنی میسازم که هم برای کاربران سریع است، هم برای توسعهدهندگان قابل نگهداری، و هم برای کسبوکار امن و مقیاسپذیر.»