با انتشار نسخه Next.js 13، یک دایرکتوری /app
جدید به پروژه اضافه میشود که رویکردهای جدیدتری برای rendering و fetching دادهها دارد و همچنین از جدیدترین سرور کامپوننت های React استفاده میکند.
Rendering، کدی که مینویسیم را به رابط کاربری که کاربر با آن تعامل دارد تبدیل میکند. با React 18 و Next.js 13 تغییر کاملی در نحوه رندر کردن کد React به وجود آمده است.
قبل از اینکه بخواهیم مکانیسمهای Rendering جدید با Next.js 13 را درک کنیم، میخواهیم برخی از اصطلاحات و تعاریف را دوباره مرور کنیم. در ادامه خلاصهای از این تعاریف را باهم بررسی میکنیم.
کلاینت به مرورگر دستگاه کاربر اشاره دارد که درخواستی را برای کد برنامه ما به سرور ارسال میکند. سپس پاسخ سرور را به رابطی تبدیل میکند که کاربر بتواند با آن تعامل داشته باشد.
سرور به رایانهای در مرکز داده اشاره دارد که کد برنامه ما را ذخیره میکند، درخواست مشتری را دریافت کرده، مقداری محاسبات روی آن انجام میدهد و در نهایت پاسخ مناسب را ارسال میکند.
کلاینت کامپوننتها بر روی کلاینت رندر میشوند. در Next.js، اجزای کلاینت نیز میتوانند از قبل روی سرور رندر شوند و روی کلاینت hydrate گردند.
نکتهای که وجود دارد این است که قبل از React 18، اصلیترین راه برای رندر برنامه با استفاده از React، کاملاً روی کلاینت انجام میشد.
برای استفاده از یک Client Component در Next.js، یک فایل در داخل /app
ایجاد میکنیم و قبل از هر گونه importای، دایرکتیو “use Client” را در بالای فایل اضافه مینماییم.
در ادامه یک نمونه از کلاینت کامپوننت /app/Counter.js را داریم:
'use client'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ); }
سرور کامپوننت یک مفهوم جدید است که در React 18 معرفی شده و توسط نسخه Next.js 13 در پوشه /app
پذیرفته شده است.
سرور کامپوننتها به ما این امکان را میدهند که کامپوننتها را روی سرور رندر کنیم و مقدار جاوااسکریپت ارسال شده به کلاینت را کاهش دهیم.
همه کامپوننتهای داخل دایرکتوری Next.js /app
به طور پیشفرض سرور کامپوننت هستند.
React Server Componentها این امکان را برای توسعهدهندگان فراهم میکنند تا از زیرساخت سرور استفاده کنند. قبل از معرفی سرور کامپوننتها، React فقط قادر به رندر سمت کلاینت بود. اما با معرفی سرور کامپوننتها، وابستگیهای بزرگ میتوانند به طور کامل روی سرور باقی بمانند و در نتیجه کارایی آنها افزایش یابد.
اندازه bundle جاوااسکریپت سمت کلاینت زمانی کاهش مییابد که وابستگیهای بزرگ در سرور حفظ شوند. زمانی که تعامل کاربر جدیدی وجود داشته باشد، همچنان میتوانیم از کلاینت کامپوننتها استفاده کنیم. اما به غیر از آن، اندازه bundle جاوااسکریپت زمان اجرای سمت کلاینت حداقل میباشد.
این موضوع یک پیروزی بزرگ برای React است و توسط Next.js 13 پذیرفته شده است.
نکته جالب در مورد این رویکرد جدید این است که میتوانیم در برنامه خود کلاینت کامپوننتها و سرور کامپوننتها را به هم متصل کنیم. React در پشت صحنه، به طور یکپارچه کارکرد هر دو محیط را باهم ادغام میکند.
React میتواند روی کلاینت و سرور رندر بگیرد و ما میتوانیم محیط رندر را در سطح کامپوننت انتخاب کنیم.
اگرچه میتوانیم از هر دو کلاینت کامپوننت و سرور کامپوننت در یک برنامه استفاده کنیم، اما محدودیتی در React وجود دارد که در آن نمیتوانیم یک سرور کامپوننت را در یک کلاینت کامپوننت import کنیم.
'use client'; // ❌ You cannot import a Server Component into a Client Component import MyServerComponent from './MyServerComponent'; export default function ClientComponent() { return ( <> <MyServerComponent /> </> ); }
راه حل این مشکل این است که میتوانیم یک سرور کامپوننت را به عنوان یک child یا یک prop به یک کلاینت کامپوننت ارسال کنیم، همانطور که در ادامه میبینیم:
// ✅ You can pass a Server Component as a child or prop of a Client Component. import ClientComponent from "./ClientComponent"; import ServerComponent from "./ServerComponent"; export default function Page() { return ( <ClientComponent> <ServerComponent /> </ClientComponent> ); }
'use client'; // ✅ You can pass a Server Component as a child or prop of a Client Component. export default function ClientComponent({children}) { return ( <> {children} </> ); }
ما فقط باید زمانی که کامپوننتها از هوکهای کلاینت مانند useState یا useEffect استفاده میکنند، آن ها را به عنوان “use Client” علامتگذاری کنیم.
بهتر است کامپوننتهایی که به هوکهای کلاینت وابسته نیستند را بدون دستورالعمل رها کنیم تا زمانی که توسط کلاینت کامپوننت دیگری import نمیشوند، به طور خودکار به عنوان یک سرور کامپوننت رندر شوند.
این کار کمک میکند تا از کمترین مقدار جاوااسکریپت در سمت کلاینت اطمینان حاصل کنیم. زیرا هدف ما این است که کمترین مقدار جاوااسکریپت در سمت کلاینت ارسال شود.
استفاده از Client Componentها:
onClick()
وجود دارد.استفاده از Server Componentها: