إجراءات الخادم (Server Actions)

تتكامل Next.js مع إجراءات React لتوفير حل مدمج لـ التحولات على الخادم (server mutations).

الاتفاقية

يمكنك تمكين إجراءات الخادم في مشروع Next.js الخاص بك عن طريق تفعيل العلامة التجريبية serverActions.

next.config.js
module.exports = {
  experimental: {
    serverActions: true,
  },
}

يمكن تعريف إجراءات الخادم في مكانين:

  • داخل المكون الذي يستخدمه (مكونات الخادم فقط).
  • في ملف منفصل (لمكونات العميل والخادم)، لإعادة الاستخدام. يمكنك تعريف عدة إجراءات خادم في ملف واحد.

مع مكونات الخادم

قم بإنشاء إجراء خادم عن طريق تعريف دالة غير متزامنة مع التوجيه "use server" في أعلى جسم الدالة. يضمن "use server" أن هذه الدالة تنفذ فقط على الخادم.

يجب أن تحتوي هذه الدالة على وسائط قابلة للتسلسل (serializable arguments) وقيمة قابلة للتسلسل (serializable return value).

app/page.js
export default function ServerComponent() {
  async function myAction() {
    'use server'
    // ...
  }
}

مع مكونات العميل

الاستيراد

قم بإنشاء إجراء الخادم في ملف منفصل مع التوجيه "use server" في أعلى الملف. ثم استورد إجراء الخادم إلى مكون العميل الخاص بك:

app/actions.js
'use server'

export async function myAction() {
  // ...
}
app/client-component.jsx
'use client'

import { myAction } from './actions'

export default function ClientComponent() {
  return (
    <form action={myAction}>
      <button type="submit">إضافة إلى السلة</button>
    </form>
  )
}

معلومة مفيدة: عند استخدام التوجيه "use server" في أعلى الملف، سيتم اعتبار جميع الصادرات أدناه كإجراءات خادم. يمكنك الحصول على عدة إجراءات خادم في ملف واحد.

الخصائص (Props)

في بعض الحالات، قد ترغب في تمرير إجراء خادم إلى مكون عميل كخاصية.

<ClientComponent updateItem={updateItem} />
app/client-component.jsx
'use client'

export default function ClientComponent({ myAction }) {
  return (
    <form action={myAction}>
      <input type="text" name="name" />
      <button type="submit">تحديث العنصر</button>
    </form>
  )
}

ربط الوسائط

يمكنك ربط الوسائط بإجراء خادم باستخدام طريقة bind. هذا يسمح لك بإنشاء إجراء خادم جديد مع بعض الوسائط المربوطة مسبقًا. يكون هذا مفيدًا عندما تريد تمرير وسائط إضافية إلى إجراء خادم.

app/client-component.jsx
'use client'

import { updateUser } from './actions'

export function UserProfile({ userId }) {
  const updateUserWithId = updateUser.bind(null, userId)

  return (
    <form action={updateUserWithId}>
      <input type="text" name="name" />
      <button type="submit">تحديث اسم المستخدم</button>
    </form>
  )
}

ثم سيستقبل إجراء الخادم updateUser وسيطة userId بالإضافة إلى بيانات النموذج:

app/actions.js
'use server'

export async function updateUser(userId, formData) {
  // ...
}

معلومة مفيدة: تعمل .bind لإجراء خادم في كل من مكونات الخادم والعميل. كما أنها تدعم التحسين التدريجي (Progressive Enhancement).

الاستدعاء

يمكنك استدعاء إجراءات الخادم باستخدام الطرق التالية:

  • باستخدام action: خاصية action في React تسمح باستدعاء إجراء خادم على عنصر <form>.
  • باستخدام formAction: خاصية formAction في React تسمح بالتعامل مع عناصر <button>، <input type="submit">، و <input type="image"> داخل <form>.
  • استدعاء مخصص باستخدام startTransition: استدعاء إجراءات الخادم دون استخدام action أو formAction عن طريق استخدام startTransition. هذه الطريقة تعطل التحسين التدريجي (Progressive Enhancement).

التحسين التدريجي (Progressive Enhancement)

يسمح التحسين التدريجي لـ <form> بالعمل بشكل صحيح بدون JavaScript، أو مع تعطيل JavaScript. هذا يسمح للمستخدمين بالتفاعل مع النموذج وإرسال البيانات حتى إذا لم يتم تحميل JavaScript للنموذج بعد أو إذا فشل في التحميل.

تدعم إجراءات React (سواء على الخادم أو العميل) التحسين التدريجي، باستخدام إحدى الاستراتيجيتين:

  • إذا تم تمرير إجراء خادم مباشرة إلى <form>، فإن النموذج يكون تفاعليًا حتى إذا كان JavaScript معطلاً.
  • إذا تم تمرير إجراء عميل إلى <form>، يظل النموذج تفاعليًا، ولكن سيتم وضع الإجراء في قائمة انتظار حتى يتم ترطيب النموذج. يعطي React الأولوية للإجراء، لذلك يحدث بسرعة.

في كلتا الحالتين، يكون النموذج تفاعليًا قبل حدوث الترطيب. على الرغم من أن إجراءات الخادم لها فائدة إضافية تتمثل في عدم الاعتماد على JavaScript من جانب العميل، يمكنك مع ذلك تكوين سلوك إضافي مع إجراءات العميل حسب الرغبة دون التضحية بالتفاعلية.

حد الحجم

بشكل افتراضي، الحد الأقصى لحجم جسم الطلب المرسل إلى إجراء خادم هو 1MB، لمنع استهلاك موارد الخادم المفرطة في تحليل كميات كبيرة من البيانات.

ومع ذلك، يمكنك تكوين هذا الحد باستخدام خيار serverActionsBodySizeLimit. يمكن أن يأخذ عدد البايتات أو أي تنسيق سلسلة مدعوم من البايتات، على سبيل المثال 1000، '500kb' أو '3mb'.

next.config.js
module.exports = {
  experimental: {
    serverActions: true,
    serverActionsBodySizeLimit: '2mb',
  },
}

موارد إضافية

يتم حاليًا توثيق صفحات React API التالية:

  • "use server"
  • action (🚧)
  • formAction (🚧)
  • useFormStatus (🚧)
  • useFormState (🚧)
  • useOptimistic (🚧)