۳۰ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

کار با React Server Components

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

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

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

مؤلفه‌های سرور React وسیله‌ای برای بارگذاری کار پشت یک جزء به سرور فراهم می‌کنند. این کار از ارسال جاوا اسکریپت همراه و ارائه درخواست‌های API ثانویه برای هیدراته کردن مؤلفه جلوگیری می‌کند.

مؤلفه‌های سرور React یک ویژگی پیش‌نمایش هستند که می‌توان آن را در React 18 فعال کرد.

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

قبل از اینکه به نحوه عملکرد React Server Components نگاه کنیم، بیایید در مورد دلیل آن فکر کنیم. ابتدا، توجه به این نکته مفید است که React Server Components از رندر سمت سرور (SSR) متمایز است. به عنوان RFC از تیم React ایالات،

[SSR و Server Components] مکمل هم هستند. SSR در درجه اول تکنیکی برای نمایش سریع نسخه غیر تعاملی اجزای client است. پس از بارگیری HTML اولیه، همچنان باید هزینه دانلود، تجزیه و اجرای آن کامپوننت های Client را بپردازید.

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

  1. جاوا اسکریپت همراه نیازی به ارسال از طریق سیم به مشتری ندارد. جاوا اسکریپت وارد و اجرا می شود و نتایج روی سرور مصرف می شود.
  2. درخواست های اولیه Ajax/API برای هیدراته کردن مؤلفه لازم نیست. کامپوننت می تواند برای برآوردن این نیازها به طور مستقیم با خدمات back-end تعامل داشته باشد. این باعث می‌شود مشتری کمتر چت‌کننده‌ای داشته باشد و از «آبشار درخواست‌ها» جلوگیری می‌کند که گاهی اوقات زمانی که مرورگر واکشی داده‌های مرتبط را انجام می‌دهد دیده می‌شود.

محدودیت‌های اجزای سرور React

از آنجایی که React Server Components در چارچوب یک محیط سمت سرور اجرا می‌شوند، محدودیت‌های خاصی دارند یا اجازه دهید آنها را ویژگی بنامیم. زیرا اگرچه این ویژگی ها ممکن است از جهاتی محدودیت داشته باشند، اما به ما کمک می کنند تا بفهمیم چرا React Server Components مفید هستند.

محدودیت‌های اصلی تعیین شده توسط مشخصات، در مقایسه با اجزای معمولی سمت کلاینت:

  • بدون استفاده از حالت (به عنوان مثال، useState() پشتیبانی نمی شود). چرا؟ زیرا کامپوننت یک بار اجرا می شود و نتایج به مشتری ارسال می شود. به عنوان مثال، کامپوننت در حالت نگهداری مشتری اجرا نمی شود.
  • هیچ رویداد چرخه حیات مانند useEffect() وجود ندارد. باز هم، چون مؤلفه در مرورگر اجرا نمی‌شود و می‌تواند از رویدادها و عوارض جانبی استفاده کند.
  • هیچ API فقط برای مرورگر مانند DOM وجود ندارد، مگر اینکه آن‌ها را روی سرور چندپر کنید. به طور خاص به API واکشی فکر کنید که در آن موتورهای رندر سمت سرور معمولاً یک polyfill ارائه می‌کنند تا عملکرد سمت سرور از نظر تماس‌های API دقیقاً شبیه مرورگر به نظر برسد.
  • بدون قلاب سفارشی که به حالت یا افکت‌ها یا توابع کاربردی وابسته به APIهای فقط مرورگر بستگی دارد. اینها فقط نتیجه محدودیت های رسیدگی است.
داشبوردهای Steampipe و معیارهایی برای داده های شما

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

  • استفاده از منابع داده فقط سرور مانند پایگاه‌های داده، سرویس‌های داخلی و سیستم‌های فایل. به طور خلاصه، کامپوننت به محیط گره ای که در آن زندگی می کند دسترسی کامل دارد.
  • استفاده از قلاب سرور. دسترسی به قابلیت‌های سمت سرور مانند سیستم فایل را می‌توان در قلاب‌هایی قرار داد تا عملکرد را با روحیه مشابه قلاب‌های معمولی به اشتراک بگذارد.
  • امکان ارائه سایر اجزای سمت سرور، عناصر بومی (div، span، و غیره)، و اجزای سمت سرویس گیرنده.

آخرین مورد را در نظر داشته باشید. React Server Components در یک درخت سلسله مراتبی از مؤلفه ها وجود دارد که هر دو مؤلفه سرور و مؤلفه های سرویس گیرنده را که در داخل یکدیگر قرار گرفته اند، مخلوط می کند.

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

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

استفاده از React Server Components

از آنجایی که در حال حاضر دو نوع مؤلفه وجود دارد، آنها را با استفاده از server.js و client.js (و سایر پسوندهای مرتبط مانند server.jsx و client.jsx) به ترتیب برای مؤلفه های سرور و مؤلفه های سرویس گیرنده متمایز می کنید. توجه داشته باشید که مؤلفه های client.js چیز جدیدی نیستند. آنها دقیقاً مانند اجزای React هستند که قبلاً با آنها آشنا بودید، فقط آنها اکنون پسوند فایل دارند تا موتور بداند کدام یک هستند.

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

به منبع NoteList.server.js در فهرست ۱ نگاهی بیندازید.

فهرست ۱. NoteList.server.js

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>
  );
}

چند چیز در اینجا نشان داده شده است. ابتدا به polyfill برای fetch API در خط ۱ توجه کنید که توسط react-fetch ارائه شده است. مجدداً، به شما اجازه می‌دهد درخواست‌های API را بنویسید که دقیقاً شبیه اجزای مشتری هستند.

Flowpipe: یک موتور گردش کار برای توسعه دهنده اسکریپت

دوم، مشاهده کنید که چگونه از طریق یک API یکپارچه (وارد کردن db) به datastore دسترسی پیدا می‌کند. این یک کنوانسیون است که توسط تیم React ارائه شده است. از نظر تئوری می‌توانید از طریق یک Node API معمولی به پایگاه داده ضربه بزنید. در هر صورت، متغیر notes با ضربه زدن مستقیم به پایگاه داده پر می شود، جایی که کد با اخطارهایی مبنی بر عدم انجام این کار در زندگی واقعی توضیح داده می شود (در مقابل تزریق SQL آسیب پذیر است).

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

چهارم و در آخر، ببینید چگونه مؤلفه SideBarNote مانند هر مؤلفه دیگری وارد می شود، حتی اگر یک مؤلفه سمت کلاینت است که در فایل SideBarNote.client.js تعریف شده است.

اجزای بدون بسته

یکی از قانع‌کننده‌ترین چیزها در مورد React Server Component این است که جاوا اسکریپتی که مؤلفه به آن وابسته است – بسته‌های شخص ثالثی که وارد می‌شوند – لازم نیست برای مشتری ارسال شود. آنها به طور کامل روی سرور وارد شده، تفسیر می شوند و از ما ساخته می شوند. فقط نتیجه ارسال می شود.

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

تقسیم کد بهبود یافته

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

این شبیه به استفاده از React.lazy() برای وارد کردن کد است، با این تفاوت که تقسیم بدون مداخله انجام می‌شود. بعلاوه، مؤلفه سرور می‌تواند زودتر از مؤلفه مشتری، مسیر کد لازم را بارگیری کند که باید منتظر بماند تا مسیر تصمیم بارگیری و اجرا شود.

آموزش Golang: با زبان Go شروع کنید

نمونه ذکر شده توسط RFC در فهرست ۲ است که ارزش نگاهی گذرا به آن را دارد.

فهرست ۲. بارگذاری تنبل در یک جزء سرور

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</code >). اگر این کار با React.lazy انجام می‌شد، مؤلفه در اینجا باید در مرورگر ارزیابی می‌شد قبل از اینکه انتخاب لازم با تنبلی بارگیری شود. در عوض، با یک جزء سرور، استفاده از Lazy مورد نیاز نیست، و به محض اجرای این کد در سرور، مسیر کد صحیح شروع به بارگیری کند.

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

به نقل قول زیر از React Server Components RFC توجه کنید:

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

جالب است. بنابراین React Server Components عملاً چیزی شبیه به SSR انجام نمی‌دهند، که به موجب آن کامپوننت بر روی سرور رندر می‌شود و به HTML و حداقل JS برای بوت استرپ کردن خود روی کلاینت کاهش می‌یابد. در عوض، فریم ورک در واقع به محض آماده شدن حالت رابط کاربری مقطر را پخش می‌کند.

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

این بدان معناست که همانطور که نقل قول RFC اشاره می کند، عناصر ضروری UI را می توان در اسرع وقت شناسایی و ارائه کرد. در همین حال، Suspense می تواند برای مدیریت هوشمندانه بخش های تعاملی سمت مشتری استفاده شود.

React meets Server

مؤلفه‌های سرور React حرکتی جسورانه برای چنین پروژه جاوا اسکریپت محبوب با پشتیبانی شرکتی را نشان می‌دهند. این به وضوح به جهان اعلام می کند که React و تیم آن متعهد به مشارکت در شلوغی مداوم نوآوری در چارچوب های جاوا اسکریپت هستند.

تیم React که راضی به رویارویی خود نیستند، روی همان سؤالاتی کار می کنند که سایر نوآوران از Svelte تا Qwik تا SolidMarko و Astro) در حال فکر کردن هستند.