نحوه کار با React Server Components در فریم ورک React

شنبه 23 بهمن 1400

فریم ورک React همچنان یکی از بهترین فریم ورک های فرانت اند زبان برنامه نویسی جاوا اسکریپت به شمار می آید و تیم سازنده فریم ورک React همچنان به دنبال راهکارهایی هستند تا بتوانند آن را در صدر لیست بهترین فریم ورک های این زبان نگه دارند.

 نحوه کار با React Server Components در فریم ورک React

یکی از پیشرفت های بسیار مهمی که در نقشه راه این فریم ورک رخ داده است کامپوننت های سرور React هستند. React Server Components یک ابزار بسیار قدرتمند در فریم ورک React است که به شما اجازه می دهد وظیفه پشت کامپوننت ها را به راحتی در سرور بارگذاری کنید. این ابزار از استفاده از جاوا اسکریپت ship bundled و همینطور از داشتن درخواست های API ثانویه سرور جلوگیری می کند. کامپوننت های سرور فریم ورک React یک ویژگی پیش نمایش است که از نسخه 18 فریم ورک React  فعال شده است. در ادامه بیشتر درباره این ابزار و ویژگی های منحصر به فرد آن صحبت خواهیم کرد.

چرا باید از React Server Components استفاده کنیم؟

پیش از آن که بخواهیم درباره نحوه کار React Server Components صحبت کنیم اجازه دهید تا درباره این موضوع صحبت کنیم که چرا باید از این ابزار در فریم ورک React استفاده کنیم. اولین نکته ای که در این خصوص باید به آن توجه داشته باشید این است که React Server Components با رندر سمت سرور(SSR) متفاوت است. در واقع SSR و کامپوننت های سرور مکمل یکدیگر هستند. SSR در درجه اول تکنیکی برای نمایش سریع کامپوننت های کلاینت که شامل نسخه های غیرتعاملی هستند می باشد. پس از بارگذاری کدهای HTML اولیه شما همچنان باید هزینه دانلود، آنالیز و اجرای این کامپوننت های کلاینت را بپردازید.

بنابراین برخلاف SSR که در آن قصد داریم نسخه اولیه یک کامپوننت را ارائه دهیم  React Server Components می تواند به طور کامل عملکرد سمت کلاینت را با کارهای انجام شده روی سرور جایگزین کند.

دو مزیت مهم این ابزار در فریم ورک React

عملکردی که این ابزار در فریم ورک React از خود نشان می دهد به طور کلی دو فایده و مزیت اصلی دارد:

-          نیازی نیست که کدهای جاوا اسکریپت بسته بندی شده به صورت دائمی به کلاینت ارسال شوند. در واقع با این کار جاوا اسکریپت import و اجرا می شود و سپس کدهای آن در سرور مورد استفاده قرار می گیرند.

-          درخواست های اولیه Ajax/API برای hydrate کردن کامپوننت نیاز نخواهد بود. این کامپوننت می تواند به صورت مستقیم با سرویس های بک اند تعامل داشته باشد تا این نیازها را به خوبی برآورده کند. این ویژگی باعث می شود تا نیاز به کدهای کمتری وجود داشته باشد و از هدر رفتن زمان توسط مرورگر در حین واکشی کردن داده های مرتبط جلوگیری می کند.

محدودیت های React Server Components در فریم ورک React

از آنجایی که React Server Components در چارچوب یک محیط سمت سرور اجرا می شود دارای محدودیت های خاصی هستند که باید آنها را جزئی از مشخصات این ابزار قرار دهیم چرا که شاید در برخی از روش ها این مشخصات یک محدودیت به شمار بیایند ولی با این حال به ما کمک می کنند تا بهتر درک کنیم که چرا React Server Components می تواند مفید باشد.

از جمله اصلی ترین محدودیت های این ابزار در فریم ورک React در مقایسه با کامپوننت های معمولی سمت کلاینت شامل موارد زیر است:

-          عدم استفاده از state( به عنوان مثال useState() پشتیبانی نمی شود) چرا که کامپوننت یک بار اجرا می شود و سپس نتیجه آن به عنوان یک جریان به کاربر ارائه می شود. به عبارت دیگر کامپوننت در state نگهداری کلاینت اجرا نمی شود.

-          هیچ رویداد چرخه حیاتی مانند useEffect() در آن وجود ندارد. مجددا دلیل این موضوع این است که کامپوننت در مرورگر اجرا نمی شود تا بتواند از مزایای رویدادها و سایر موارد این چنینی بهره مند شود.

-          هیچ browser-only API مانند DOM در آن وجود ندارد مگر آن که شما خودتان آنها را روی سرور قرار دهید. به عنوان مثال شما می توانید fetch API را در نظر بگیرید که در آن موتورهای رندر سمت سرور یک polyfill را فراهم می کنند و به این ترتیب عملکرد سمت سرور دقیقا مشابه مرورگر خواهد بود با این تفاوت که فراخوانی های API را نیز مدنظر قرار می دهد.

-          هیچ hook سفارشی سازی شده ای که به state یا افکت ها وابسته باشد یا توابع utility که به  browser-only API ها وابسته هستند وجود ندارد.

قابلیت هایی که توسط React Server Components پشتیبانی شده ولی توسط کامپوننت های سمت کلاینت پشتیبانی نمی شوند

-          استفاده از داده هایی که تنها مبتنی بر سرور هستند مانند پایگاه داده ها، سرویس های داخلی و سیستم های مربوط به فایل ها: به طور خلاصه می توان گفت که در فریم ورک React با استفاده از این ابزار کامپوننت می تواند دسترسی کاملی به محیط اصلی که در آن قرار دارد داشته باشد.

-          استفاده از hook های سرور: دسترسی به قابلیت های سمت سرور مانند سیستم فایل می تواند در hook محصور شود تا عملکرد را از طریق یک spirit یکسان و مشخص به عنوان hook های معمولی به اشتراک بگذارد.

-          قابلیت رندر کردن سایر کامپوننت های سمت سرور، عناصر نیتیو(div، span و ...) و کامپوننت های سمت کلاینت

نکاتی درباره محدودیت های این ابزار در فریم ورک React

یک نکته بسیار مهم که باید درباره این ابزار در فریم ورک React بدانید این است که React Server Components در یک درخت سلسله مراتبی از کامپوننت ها قرار دارد که می تواند کامپوننت های سمت سرور و سمت کلاینت را با یکدیگر ترکیب کرده و آنها را در داخل یکدیگر قرار دهد.

علاوه بر این باید توجه داشته باشید که React Server Components به هیچ وجه جایگزین سایر بخش های اکوسیستم فریم ورک react نمی شوند. به طور خاص React Server Components جایگزین کامپوننت های معمولی کلاینت نمی شوند. در عوض آنها کامپوننت های کلاینت را به شکلی تقویت می کنند که به شما اجازه می دهند تا کامپوننت های سرور را نیز در صورت لزوم وارد درخت کنید.

یک نکته مهم درباره React Server Components

توجه داشته باشید که React Server Components هنوز هم می تواند prop ها را به کامپوننت های کلاینت فرزند خود ارسال کند. این به آن معناست که شما می توانید به طور هوشمندانه ای اپلیکیشن خود را به بخش های تعاملی تقسیم بندی کرده، آنها را توسط کامپوننت های کلاینت مدیریت کرده و کامپوننت های سرور را نیز به آنها اضافه کنید که state شما را در واحد زمان از سمت بک اند بارگذاری کنند.

استفاده از React Server Components در فریم ورک React

از آنجایی که در حال حاضر دو نوع کامپوننت وجود دارد شما می توانید آنها را با استفاده از server.js و  client.js تشخیص دهید ( یا این که از سایر افزونه ها برای انجام این کار استفاده کنید). دقت داشته باشید که کامپوننت های client.js چیز جدیدی نیستند. آنها دقیقا مانند کامپوننت های فریم ورک React هستند که قبلا نیز با آنها آشنا شده اید تنها تفاوت آنها این است که یک افزونه فایل دارند تا موتور دقیقا متوجه شود که نوع آنها چیست.

اگر شما به اپلیکیشن دمویی که توسط تیم توسعه دهنده فریم ورک React طراحی و ساخته شده است نگاه کنید مشاهده خواهید کرد که فایل ها داخل پوشه /src درهم آمیخته شده و به یکدیگر وابسته هستند. از جمله این فایل ها می توان به NoteList.server.js و SideBarNote.client.js اشاره کرد.

بررسی فایل NoteList.server.js

اجازه دهید تا در قطعه کد زیر نگاهی به فایل NoteList.server.js داشته باشیم تا بیشتر با عملکرد آن در فریم ورک React آشنا شویم:

import {fetch} from 'react-fetch';

import {db} from './db.server';
import SidebarNote from './SidebarNote';

export default function NoteList({searchText}) {

  // const notes = fetch('http://localhost:4000/notes').json();
  // WARNING: This is for demo purposes only.
  // We don't encourage this in real apps. There are far safer ways to access data in a real application!
  const notes = db.query(
    `select * from notes where title i like $1 order by id desc`,
    ['%' + searchText + '%']
  ).rows;

  // Now let's see how the Suspense boundary above lets us not block on this.
  // fetch('http://localhost:4000/sleep/3000');

  return notes.length > 0 ? (
    <ul className="notes-list">
      {notes.map((note) => (
        <li key={note.id}>
          <SidebarNote note={note} />
        </li>
      ))}
    </ul>
  ) : (
    <div className="notes-empty">
      {searchText
        ? `Couldn't find any notes titled "${searchText}".`
        : 'No notes created yet!'}{' '}
    </div>
  );
}

توضیحاتی درباره قطعه کد بالا در فریم ورک React

در قطعه کد بالا چندین مورد مختلف درباره فریم ورک React وجود دارد که باید درباره آنها صحبت کنیم. ابتدا به polyfill که برای fetch API در خط اول مورد استفاده قرار گرفته است توجه کنید که توسط  react-fetch فراهم شده است. مجددا باید دقت داشته باشید که این قابلیت به شما اجازه می دهد تا درخواست های API را به شکلی بنویسید که شبیه به کامپوننت های کلاینت در نظر گرفته شوند. نکته دوم این است که چگونه از طریق یک API واحد (import کردن db) datastore کاملا در دسترس قرار گرفته است. این یک قاعده مهم است که توسط تیم توسعه دهندگان فریم ورک react ارائه شده است. از نظر تئوری شما می توانید با استفاده از یک node API معمولی به پایگاه داده خود آسیب بزنید. هر هر رویدادی متغیرهای notes از طریق ضربه زدن این چنینی به پایگاه داده جمع آوری می شوند.

به عنوان نکته سوم توجه کنید که چگونه بدنه قالب view به صورت JSX معمولی است که با استفاده از return تابع تعریف شده است.

به عنوان نکته چهارم نیز باید دقت داشته باشید که چگونه SideBarNote مانند هر کامپوننت دیگری import می شود حتی اگر یک کامپوننت سمت کلاینت باشد که در فایل  SideBarNote.client.js تعریف شده است.

کامپوننت های No-bundle در فریم ورک React

یکی از جذاب ترین نکاتی که درباره React Server Component وجود دارد این است که جاوا اسکریپتی که کامپوننت به آن وابسته است( بسته های شخص ثالثی که import شده اند) نیازی نیست که برای کلاینت ارسال شود. آنها به طور کامل روی سرور import، تفسیر و ساخته می شوند و تنها نتیجه برای ما ارسال می شود. به عنوان مثال اگر به فایل Note.server.js نگاهی بیندازید مشاهده خواهید کرد که یک ابزار فرمت کردن داده را import کرده است ( از طریق  import {format} from 'date-fns';) که همه چیز از طریق آن در سرور اتفاق می افتد. علاوه بر این شما از استفاده نادرست از داده های خود نیز جلوگیری خواهید کرد.

قابلیت جداسازی بهینه کدها

یکی دیگر از حوزه های فریم ورک React که در آن شاهد موفقیت و عملکرد بسیار خوب React Server Component هستیم قابلیت جداسازی و تقسیم کد است. دلیل این موضوع این است که کامپوننت سرور در زمان اجرا نمی تواند مشخص کند که کدام مسیر کد در حال اجرا است و در نتیجه درباره کدی که در حال اجرا شدن است تصمیم بگیرد. در واقع این کار شبیه به استفاده از React.lazy() برای import کردن کد است با این تفاوت که جداکردن و تقسیم کد در این جا بدون مداخله صورت می گیرد. علاوه بر این باید دقت داشته باشید که مولفه سرور می تواند سریع تر از مولفه سرویس گیرنده مسیر کد لازم را بارگذاری کند.

مثالی از Lazy loading در سرور کامپوننت 

در ادامه مثالی را درباره این موضوع به شما ارائه خواهیم داد:

import React from 'react';

// one of these will start loading *once rendered and streamed to the client*:
import OldPhotoRenderer from './OldPhotoRenderer.client.js';
import NewPhotoRenderer from './NewPhotoRenderer.client.js';

function Photo(props) {
  // Switch on feature flags, logged in/out, type of content, etc:
  if (FeatureFlags.useNewPhotoRenderer) {
    return <NewPhotoRenderer {...props} />;
  } else {
    return <OldPhotoRenderer {...props} />;
  }
}

در قطعه کد بالا ما درباره این که کدام کامپوننت (OldPhotoRenderer یا NewPhotoRenderer) براساس یک فلگ (FeatureFlags.useNewPhotoRenderer) باید بارگذاری شود تصمیم گیری کردیم. اگر این کار با استفاده از React.lazy انجام شود پیش از آن که انتخاب مدنظر ما به این شکل بارگذاری شود کامپوننت فعلی باید روی مرورگر ارزیابی شود و به محض این که این کد روی سرور اجرا شود مسیر کد صحیح نیز به همین شکل بارگذاری خواهد شد.

React Server Components چگونه در فریم ورک React کار می کند؟

کامپوننت های سرور به صورت تدریجی رندر می شوند و واحدهای رندر شده از UI را به صورت افزایشی برای کلاینت پخش می کنند. زمانی که این قابلیت را با Suspense ترکیب می کنیم به توسعه دهندگان اجازه خواهد داد تا state های بارگذاری intentional را ایجاد کرده و به سرعت محتوای مهم را به کاربر نشان دهند در حالی که باقی صفحه منتظر بارگذاری سایر بخش ها می باشد.

این ویژگی بسیار جذاب خواهد بود. بنابراین React Server Components در فریم ورک React عملکردی مشابه SSR را به شما ارائه نمی دهند که در آن کامپوننت ها در سمت سرور اجرا شده و به کدهای HTML کاهش پیدا می کند و در گام بعدی نیز با استفاده از قطعه کدهایی از جاوا اسکریپت و بوت استرپ برای کلاینت نشان داده می شوند. در عوض این قابلیت در فریم ورک React به محض آماده شدن بخش های مهم محتوا آنها را برای کلاینت پخش می کند.

فرض کنید که سرور با شرایطی مواجه شود که نیاز داشته باشد تا یک کامپوننت سرور را رندر کند. به محض این که رندر آماده می شود نتایج در یک قالب فشرده قرار می گیرند که بلافاصله شروع به پخش برای کلاینت می کند. به عبارت دیگر عناصر UI که مشاهده آنها برای کلاینت ضروری است به محض آماده شدن برای او پخش می شوند تا سایر عناصر و محتوای صفحه سایت نیز آماده شود.

نکاتی درباره React meets server

React Server Components در فریم ورک React یک حرکت بسیار جسورانه برای چندین پروژه محبوب جاوا اسکریپت را ارائه کرده است. این حرکت به وضوح به جهان اعلام می کند که فریم ورک React و تیم توسعه دهندگان آن متعهد به مشارکت در نوآوری های جدید فریم ورک های زبان برنامه نویسی جاوا اسکریپت هستند. 

 

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

تاکنون هیچ کاربری از این پست تشکر نکرده است

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید