التغيير الغير متزامن للبيانات ومعالجتها هو مهمة ضرورية في التطبيقات الويب الحديثة. قد ترغب في تنفيذ دالة غير متزامنة مستقلة على الخادم لتنفيذ مهام مثل حفظ البيانات في مخزن البيانات، إرسال البريد الإلكتروني، تحميل ملفات PDF، معالجة الصور، وهلم جرا.

Next.js يوفر لنا Server Actions التي هي دوال غير متزامنة تنفذ على الخادم. يمكننا استخدام إجراءات الخادم لتغيير البيانات على الخادم، ولكن يمكن استدعاء إجراءات الخادم من كل من مكونات الخادم والعميل.

إجراءات الخادم هي طريقة رائعة لمعالجة تقديم النماذج عن طريق تنفيذ الإجراء عندما يتم تقديم بيانات النموذج. في هذه المقالة، سننظر في حالة استخدام عملية لمعالجة وسائط إضافية في إجراءات خادم Next.js.

إذا كنت مهتمًا بتعلم إجراءات خادم Next.js مع أنماط التصميم وبناء المشروع، فقد أنشأت دورة مكثفة لك يمكنك العثور عليها هنا.

كما أن هذه المقالة متاحة أيضًا كدرس فيديو هنا:

جدول المحتويات

  1. لماذا قد تحتاج إلى تمرير وسائط إضافية؟

  2. نموذج مع إجراء خادم

  3. كيف تتم تقديم المادة الإضافية

  4. ماذا عن الحقول الخفية؟

  5. موارد

لماذا قد تحتاج إلى تقديم المادة الإضافية؟

عندما ننفذ عملية خادم في تسجيل النموذج، يتلقى العملية الخادمية على المعلومات التي تتم تسجيلها بشكل تلقائي. على سبيل المثال، ألقو نظرة على النموذج التالي:

<form className="p-4 flex" action={updateUser}>
  <Input className="w-1/2 mx-2" type="text" name="name" />
  <Button type="submit">Update User Name</Button>
</form>

في هذه الحالة ننفذ عملية خادم تدعى updateUser حين تُقبل النموذج. ستتلقى وظيفة updateUser المعلومات التي تم تسجيلها من النموذج كمادة من المعلومات التي يمكن استخراج قيم الحقول منها.

كما ترون في مقطع البرمجيات التالي، ستتلقى وظيفة updateUser مادة formData كمادة من المعلومات، ويمكننا استخراج قيمة حقول الإسم name منها.

"use server"

export async function updateUser(formData) {
  const name = formData.get('name');
  console.log(name);
}

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

لفهم هذا، قم برؤية مقطع الكود الخاص بالعملية السرورية أدناه. إنها نفس العملية السرورية التي رأيناها من قبل، لكن أضفنا معارف إضافية userId بجانب المعارف المعتادة formData.

"use server"

export async function updateUser(userId, formData) {
  const name = formData.get('name');
  console.log(userId);
  console.log(name);
}

قيمة userId شيء داخلي للتطبيق ولن تطلب من المستخدم تقديم القيمة كجزء من تسجيل النموذج. بل قد تحتاج إلى تقديمها بشكل برمجي إلى عملية السرور لتقوم بحوسبات أكثر.

صحيح، هذه هي الحالة التي نتحدث عنها. وأماماً بفهم سبب حاجتنا إليها، دعونا نفهم كيفية إنجازها. لكن أولاً، دعونا نخلق نموذجًا وعملية سرورية فعالة له.

نموذج مع عملية سرورية

قم بإنشاء دراجة تدعى actions تحت دراجة app لتطبيقك الNext.js. ومن ثم قم بإنشاء ملف user.js في الدراجة actions بالإشارة التالية:

"use server"

export async function updateUser(formData) {
  const name = formData.get('name');
  console.log(name);

  // قم بأي شيء تريد بالإسم، حفظه في القاعدة البياناتية، إنشاء فاتورة، أياً كان!
}

هذه هي طريقة إنشاء وظيفة سرورية في Next.js. ي

لذا فلدينا العملية الخاصة بال serve r(المادة المتنقلة) updateUser مع formData كمارجع. داخل تعريف المادة، نستخرج قيمة name ونطبعها على المستوى الإعلامي.

دعونا نربط هذه العملية الخاصة بال serve rبأحد الأوراق. للقيام بذلك، قم بإنشاء مجلد يدعى components تحت مجلد جذر المشروع. قم بإنشاء ملف يدعى user-form.jsx مع ال following code:

import { Input } from "./ui/input"
import { Button } from "./ui/button"

import { updateUser } from "@/app/actions/user"

const UserForm = () => {
  return(
    <form className="p-4 flex" action={updateUser}>
      <Input className="w-1/2 mx-2" type="text" name="name" />
      <Button type="submit">Update User Name</Button>
    </form>
  )
}

export default UserForm;

هذه مكونة راكت بسيطة مع أحد الأوراق. الأوراق له حقل متحدث واحد يدعى name وزر تقديم لتقديم الأوراق. للأوراق خاصية action مع قيمة عملية ال serve rupdateUser كقيمة. الآن، عندما يتم تقديم الأوراق مع قيمة name، ستحصل علىها عملية ال serve rكجزء من البيانات الخاصة بالأوراق، كما تحدثنا عن ذلك أعلاه.

دعونا نفتحه. للقيام بذلك، سننشئ مسار لNext.js وصفة حيث نستطيع استخدام المكونة UserForm. قم بإنشاء مجلد يدعى extra-args تحت مجلد app. والآن، قم بإنشاء ملف يدعى page.js تحت مجلد app/extra-args مع ال following code:

import UserForm from "@/components/user-form";

const ExtraArgsDemo = () => {
  return (
    <UserForm />
  )
}

export default ExtraArgsDemo;

هذه مكونة راكت بسيطة حيث قمنا باستيراد UserForm مكونة واستخدمناه في ال JSX. قم بتشغيل المخزن المحلي واستعرض هذه المسارة localhost:3000/extra-args. يجب أن ترى الأوراق مع حقل متحدث وزر.

أكتب بعض النص في الحقل المتحدث وانقر على الزر.

الآن، سوف تتمكن من رؤية أن النص المكتوب قد مكتوب على المحرك الخاص بالخوادم. لماذا على المحرك الخاص بالخوادم وليس على المحرك الخاص بالمتصفح العميل؟ ذلك لأن أفعال الخوادم تنجز على الخوادم وليس على الجهة الزائدة الخاصة بالمتصفح.

لذلك، مع هذا نحن نقدر على تأسيس تدفق البيانات بالتالي:

صفحة => نموذج => عملية الخوادم

توفر الصفحة نموذجًا. تنفذ النموذج عملية الخوادم بعد التسجيل. تقوم عملية الخوادم بطباعة البيانات من النموذج على المحرك الخاص بالخوادم.

دعونا نحسن هذه الأجزاء الآن لتمرير معاملات إضافية إلى عملية الخوادم.

كيف تمرير معاملات إضافية

دعونا نمر معاملة UserForm من الصفحة. سنمنحها معاملة userId مع قيمة للمزيد من التظاهر بأننا نمنح هذا ال

import UserForm from "@/components/user-form";

const ExtraArgsDemo = () => {
  return (
    <UserForm userId={"1234"} />
  )
}

export default ExtraArgsDemo;

userId البرمجي إلى قاعدة بياناتنا وإلى عملية الخوادم من هناك.

يوجد في JavaScript متقن يدعى bind() يساعدنا على إنشاء معاملة Partially Applied Function. مع هذه المعاملة المتعلقة بالإنتباه، يمكنك إنشاء معاملة من معاملة أخرى بمعاملات معروفة.

في حالتنا، تحتوي وظيفة updateUser بالفعل على وسيط يسمى formData. الآن يمكننا تمرير userId كوسيط إضافي باستخدام طريقة bind() لإنشاء وظيفة جديدة.

const updatedUserWithId = updateUser.bind(null, userId);

الوسيط الأول لطريقة bind() هو السياق الذي تربط به الوظيفة. يتعامل السياق مع ارتباط الوظيفة بقيمة الكلمة المفتاحية this. في حالتنا، يمكننا إبقاءه null لأننا لا نقوم بتغييره. بعد ذلك، قمنا بتمرير الوسيط الجديد userId. من الجيد معرفة أن طريقة bind() تعمل على كل من مكونات الخادم والعميل.

إليك مكون UserForm المعدل (ملف user-form.jsx). لاحظ أن قيمة إجراء النموذج تم تعديلها الآن إلى الوظيفة الجديدة updatedUserWithId.

import { Input } from "./ui/input"
import { Button } from "./ui/button"

import { updateUser } from "@/app/actions/user"

const UserForm = ({userId}) => {
  const updatedUserWithId = updateUser.bind(null, userId);

  return(
    <form className="p-4 flex" action={updatedUserWithId}>
      <Input className="w-1/2 mx-2" type="text" name="name" />
      <Button type="submit">Update User Name</Button>
    </form>
  )
}

export default UserForm;

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

"use server"

export async function updateUser(userId, formData) {
  const name = formData.get('name');
  console.log(userId);
  console.log(name);

  // قم بأي شيء مع معرف المستخدم والاسم، حفظه في قاعدة البيانات،
  // إنشاء فاتورة، أي شيء!
}

الآن إذا قمت بإرسال النموذج بقيمة اسم:

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

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

ماذا عن الحقول المخفية؟

HTML يدعم حقل نوع مخفي للمربع التقاءي لتحميل بيانات المستخدم إلى ال服务器 بدون قبول المعطيات من المستخدمين. إذا هذا يعني أنه يمكننا أن نستخدم الحقل المخفي لتحميل قيمة userId بتلك الطريقة:

لكن لماذا قمنا بكل هذا بواسطة مétodo bind()؟ حسنًا بسبب المخاطر الأمنية. عندما تقوم بتحميل البيانات بواسطة الحقول المخفية، ستكون القيمة جزءًا من الHTML المنسجم، ولن تكون مكونة بالترميز. إذا فإنه أفضل أن نتعامل بالبرمجية.

المصادر

هذا كل ما لدينا لحظ الآن. هل أستمتعت بقراءة هذه المقالة وهل تعلمت شيئًا جديدًا؟ إذا كان ذلك هو حال، سأحب معرفة إن كان المحتوى مساعدًا. دعوني أشارك بعض المصادر الإضافية التي قد تحتاجوا إليها:

بالإضافة إلى ذلك، يمكنك الاتصال بي عن طريق:

  • التسجيل في قناتي على YouTube الخاصة بي. إذا كنت من المستعدين لتعلم React وبيئتها الاقتصادية، مثل Next.js، بالمبادئ الأساسية والمشاريع، لدي أخبار جيدة لك: يمكنك البحث عن هذه القائمة التدريبية على قناتي على YouTube مع 25+ محادثة تعليمية وأكثر من 15 ساعة من المحتوى المشغول حتى الآن، مجانا. أتمنى أن تعجبكم بهذه المحتويات أيضًا.

  • تتبعوني عبر X (Twitter) أو LinkedIn إذا لم تريد أن تفوت القدر من النصيحة اليومية للتعلم المتقدم.

  • البحث عن وتتبع عملي المفتوح المصدر على GitHub.

  • أنا أنشر بارحالة من المنشورات المعنية على مدونتي GreenRoots Blog، قد تجدوا أنها مفيدة أيضًا.

سأراكم قريبًا بمقالتي القادمة. حتى ذلك الحين، أتمنى لكم أن تهتموا بالنفسيات، وتواصلوا بالتعلم.