استخدام React 18 مع Next.js

من موسوعة حسوب

أضافت React 18 ميزات جديدة بما فيها ميزة تعليق تنفيذ مكوّن Suspense والترميم batching التلقائي للتحديثات والدلة startTransition الشبيهة بدوال الواجهات البرمجية، بالإضافة إلى الواجهة البرمجية الجديدة لنقل البيانات التي تُصيَّر من جانب الخادم وتدعم React.lazy، علمًا أنّ Next.js تزوّدك أيضًا بواجهة برمجية مشابهة لنقل البيانات المتواصل.

ولاستخدام React 18 مع Next.js ثبِّت آخر إصدار من React كالتالي:

npm install next@latest react@latest react-dom@latest

وهكذا ستصبح قادرًا على استخدام ميزتي startTransition و Suspense في Next.js.

أقنية النقل المتواصل للبيانات المصيرة من جانب الخادم

تتضمن تحسينات معمارية لأداء التصيير من جانب الخادم SSR عن طريق استخدام الدالة Suspense في مكوّنات React في نمط أقنية التصيير من جانب الخادم streaming SSR mode كي تُصيِّر React المحتوى على الخادم ثم تنقل التحديثات التي تجري على المحتوى من خلال قنوات HTTP.

تعتمد مكوّنات خادم React (كميزة تجريبية) على مفهوم النقل المتواصل للبيانات، ويمكن الاطلاع أكثر على مكوّنات الخادم المتعلقة بواجهة نقل البيانات في توثيق Next.js المتعلق بالموضوع، لكننا سنركز هنا على نقل البيانات في React 18.

استخدام النقل المتواصل للبيانات المُصيَّرة من جانب الخادم

لن تحتاج إلى أية إعدادات إضافية لاستخدام أقنية البيانات المصيَّرة على الخادم عند استخدام ميزة التعليق Suspense في الصفحات المُصيَّرة من جانب الخادم. يمكن أن تُستخدم أقنية النقل المتواصل للبيانات عند النشر من قبل البنية التحتية للمنصة مثل الدوال الحدية في Vercel (خلال زمن التشغيل) أو خادم Node.js (خلال زمن التشغيل). لا تدعم دوال AWS Lambda حاليًا الاستجابات الخاصة بأقنية البيانات.

تمتلك معظم صفحات SSR القدرة على تصيير المكوّنات إلى قنوات نقل قادرة على توصيل التحديثات باستمرار إلى العميل حتى بعد وصول الاستجابة الأولية التي أرسلها الخادم. عندما ينتهي العمل على أي مكوّن معلَّق سيُصيِّره الخادم وينقله إلى العميل. ويعني هذا قدرة التطبيقات على بث محتوى HTML المتوفِّر حتى قبل وصول جميع البيانات اللازمة مما يؤثر إيجابًا على أداء تحميل الصفحات.

وكميزة إضافية، بإمكان العميل في نمط أقنية التصيير من جانب الخادم استخدام أسلوب الترطيب الانتقائي selective hydration لاختيار أولوية ترطيب المكوّنات (تنفيذ شيفرة JavaScript الخاصة بها) وفقًا لتفاعل المستخدم وهذا ما يحسّن أداء التحميل أيضًا.

ستبقى المكوِّنات المعلّقة الحدودية react-suspense-boundary خاضعة للتحسين الساكن في الصفحات التي لا تُصيَّر من جانب الخادم، راجع توثيق أقنية نقل SSR لمعلومات أوفى.

الميزات المتاحة مع أقنية نقل البيانات

تدعم Next.js ميزة التحميل المحدود أو الكسول للمكتبات الخارجية باستخدام ()import ولمكوّنات React باستخدام next/dynamic. يُساعد تأجيل التحميل في تحسين أداء التحميل ككل بنقليل كمية JavaScript المطلوبة لتصيير الصفحة. إذ تُدرج المكوّنات أو المكتبات وتُضم إلى تجميعة JavaScript عند استخدامها فقط. اطلع على توثيق الإدراج الديناميكي في Next.js لمعلومات أكثر.

ملاحظات هامة

استخدام next/head و next/script

لن تعمل عناصر إدراج الموارد مثل السكربتات أو أوراق التنسيق في next/head كما هو مطلوب مع ميزة أقنية نقل البيانات، فلن تضمن توقيت وترتيب إدراج تلك العناصر عبر next/head بمجرد إضافة المكوّنات المعلَّقة الحدودية. لهذا ننصح في هذه الحالة بنقل عناصر إدراج الموارد إلى next/script وفق أحد الأسلوبين afterInteractive أو lazyOnload أو إلى document_. ولنفس السبب، ننصح أيضًا نقل نسخ next/script التي تستخدم استراتيجية beforeInteractive إلى document_.

إحضار البيانات

تُدعم عملية إحضار البيانات من قبل المكوّنات المعلقة الحدودية Suspense من جانب العميل فقط حاليًا، ولا تُدعم من جانب الخادم.

التنسيقات

تُعد طرق التنسيق التالية متوافقة مع أقنية نقل بيانات Next.js:

ولا تتوافق تنسيقات CSS-in-JS مثل styled-components و emotion مع أقنية نقل بيانات Next.js حاليًا.

مكوّنات خادم React (الإصدار الاختباري Alpha)

تُعد مكوّنات React ميزة جديدة تقلل حجم تجميعة JavaScript الخاصة بالتطبيق عن طريق فصل الشيفرة التي تُنفَّذ على الخادم عن شيفرة العميل، ولا تزال هذه الميزة قيد التطوير والبحث.

تتيح لك مكونات خادم React تصيير المكوّنات على الخادم، وهذا أمر مختلف من حيث المبدأ عن التصيير من جانب الخادم SSR التي تولَّد فيها شيفرة HTML على الخادم. لا حاجة مع مكوّنات الخادم لشيفرة JavaScript من جانب العميل مما يسرّع في تصيير الصفحات ويحسّن تجربة المستخدم لتطبيقك ويزاوج بين ميزات التصيير على الخادم والتفاعلية من جانب العميل.

تفعيل مكوّنات خادم React

لاستخدام مكوّنات خادم React، لا بد من تثبيت أحدث إصدار من React كالتالي:

npm install next@canary react@latest react-dom@latest

حدّث بعد ذلك ملف التهيئة next.config.js:

// next.config.js
module.exports = {
  experimental: {
    runtime: 'nodejs',
    serverComponents: true,
  },
}

يؤدي استخدام الصفة runtime إلى تفعيل أقنية بيانات SSR، كما يدفع ضبط قيمة runtime على 'edge' الخادم إلى العمل كليًا في وضع التشغيل الحدي Edge Runtime.

يمكنك الإطلاع على المثال المخصص لعمل مكوّنات خادم React مع Next.js عبر المستودع المخصص على GitHub.

تقاليد استخدام مكوّنات الخادم

لتشغيل ملف مكوّن على الخادم، أضف الامتداد server.js. إلى اسم الملف، إذ سيُعامل الملف pages/home.server.js/. مثلًا كمكوّن خادم. بينما يضُاف الامتداد client.js. تقليديًا إلى مكوّنات العميل مثل المكوّن components/avatar.client.js/.

يمكن لمكوّنات الخادم أن تُدرج في شيفرتها مكونات خادم ومكوّنات عميل، بينما لا يمكن لمكوّنات العميل إدراج مكوّنات خادم.

تتعامل Next.js مع المكوّنات التي لا تحمل امتداد مكوّن خادم client.js. ولا عميل client.js. كمكوّنات مشتركة يمكن إدراجها ضمن كلا المكوّنين. إليك مثالًا:

// pages/home.server.js

import { Suspense } from 'react'

import Profile from '../components/profile.server'
import Content from '../components/content.client'

export default function Home() {
  return (
    <div>
      <h1>Welcome to React Server Components</h1>
      <Suspense fallback={'Loading...'}>
        <Profile />
      </Suspense>
      <Content />
    </div>
  )
}

يًصيَّر المكوّنان <Home> و <Profile> من قبل الخادم دائمًا ومن ثم ينقلان عبر الأقنية إلى العميل، ولن يُضافا إلى تجميعة الخاصة بالعميل. أما المكوّن <Content> فسيُرطَّب في جانب العميل كأي مكوّن React نمطي.

انتبه إلى استخدام الإدراج والتصدير الافتراضي (باستخدام الكلمة default) لمكوّنات الخادم. إذا لايزال العمل جاريًا على دعم التصدير المُسمىّ.

واجهات Next.js البرمجية المدعومة

إليك بعض الواجهات البرمجية المدعومة في Next.js

الواجهتين next/link و next/image

يمكن استخدام شيفرة الواجهتين كالسابق تمامًا وستعاملان كمكوّنات عميل للإبقاء على التفاعلية في جانب العميل.

الواجهة next/document

لا بد من تحويل شيفرة مكوِّن المستند المخصص document_ إلى مكوّن دوال كما سنورد تاليًا لاستخدام مكوّنات الخادم. وإن لم يكن لديك مستند مخصص، ستستخدم Next.js المكوّن الافتراضي document_:

// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

الواجهة next/app

يشابه استخدام المكوّن app.js_ بنفس طريقة استخدام المكوّن App المخصص، لكن لا يُنصح باستخدام المكوّن المخصص App كمكوّن خادم مثل app.server.js_لكي يتماشى مع مكوّنات app الأخرى التي لا تعمل على جانب الخادم، بل في جانب العميل لأغراض محددة مثل إدراج تنسيقات CSS العامة.

التوجّه

يُدعم التوجه الأساسي من خلال المسار والاستعلام وكذلك التوجه الديناميكي. وإن أردت الولوج إلى موجه داخل مكوّن خادم، سيتلقى المكوّن نسخة عن الكائن router كخاصية وبهذا يمكنك الولوج مباشرة إلى معلومات الوجهة دون الحاجة إلى استخدام الخطاف ()useRouter

// pages/index.server.js

export default function Index({ router }) {
  //وغيره `router.pathname` يمكن الولوج إلى معلومات الوجهة من خلال التابع 
  return 'hello'
}

واجهات Next.js البرمجية غير المدعومة

طالما أن مكوّنات خادم React وأقنية التصيير من جانب الخادم SSR streaming في مرحلة الاختبار فلن تُدعم جميع واجهات Next.js البرمجية. لهذا سنشير إلى بعض الواجهات التي تتمتع بوظائفية محدودة ضمن مكونات الخادم، ولن يتأثر بالطبع استخدام React 18 بمعزل عن أقنية التصيير من جانب الخادم.

خطافات React

لا تُدعم حاليًا معظم خطافات React مثل useContext و useState و useReducer و useEffect و useLayoutEffect لأنّ مكوّنات الخادم لن تُنفَّذ إلا حين الطلب وهي عديمة الحالة.

إحضار البيانات والتنسيقات

لا يزال العمل جاريًا على دعم إحضار البيانات وتطبيق التنسيقات ضمن المكوّنات المعلَّقة Suspense في جانب الخادم فهي غير مدعومة جيدًا. ولا تُدعم أيضًا دوال التصدير getInitialProps و getStaticProps و getStaticPaths.

الواجهة next/head والوجهات العالمية I18n

لايزال العمل جاريًا لتقديم الدعم اللازم لها.

تبديل بيئة تشغيل التطبيق (الإصدار الاختباري Alpha)

تستخدم Next.js بيئة التشغيل Node.js افتراضيًا لتصيير الصفحات، بما في ذلك التصيير المسبق والتصيير من جانب الخادم.

ملاحظة: يؤثر الخيار runtime في الصفحات فقط ولا يؤثر في الأداة الوسطية

لكن عند تثبيت React 18، يمكنك اختبار ميزة تجريبية جديدة تسمح لك بتبديل بيئة تشغيل الصفحة بين Node.js و Edge Runtime، وستؤثر هذه العملية بالطبع على أقنية نقل البيانات المصيرة في الخادم ومكوّنات الخادم.

خيار التشغيل العام

بإمكانك ضبط قيمة الخيار التجريبي في ملف التهيئة next.config.js ليأخذ أحد القيمتين 'nodejs' أو 'edge':

// next.config.js
module.exports = {
  experimental: {
    runtime: 'nodejs',
  },
}

يحدد هذا الخيار أي من بيئتي التشغيل سيجري اعتمادها لتصيير الصفحات جميعها في زمن التشغيل.

خيار تحديد بيئة تشغيل لكل صفحة

يمكن لأي صفحة تصدير إعداد بيئة التشغيل runtime الخاصة بها لتكون 'nodejs' أو 'edge':

export const config = {
  runtime: 'nodejs',
}

ستلغي إعدادات التشغيل الخاصة بالصفحات -إن وجدت- خيار بيئة التشغيل العام التي ستستخدم افتراضيًا في حال عدم وجود إعدادات تشغيل مخصصة للصفحة.

ملاحظة: لا تدعم وجهات API حاليًا خيار تحديد بيئة تشغيل الصفحات.

المصادر

  • صفحات React 18 من توثيق Next.js الرسمي.