التغيير الغير متزامن للبيانات ومعالجتها هو مهمة ضرورية في التطبيقات الويب الحديثة. قد ترغب في تنفيذ دالة غير متزامنة مستقلة على الخادم لتنفيذ مهام مثل حفظ البيانات في مخزن البيانات، إرسال البريد الإلكتروني، تحميل ملفات PDF، معالجة الصور، وهلم جرا.
Next.js يوفر لنا Server Actions
التي هي دوال غير متزامنة تنفذ على الخادم. يمكننا استخدام إجراءات الخادم لتغيير البيانات على الخادم، ولكن يمكن استدعاء إجراءات الخادم من كل من مكونات الخادم والعميل.
إجراءات الخادم هي طريقة رائعة لمعالجة تقديم النماذج عن طريق تنفيذ الإجراء عندما يتم تقديم بيانات النموذج. في هذه المقالة، سننظر في حالة استخدام عملية لمعالجة وسائط إضافية في إجراءات خادم Next.js.
إذا كنت مهتمًا بتعلم إجراءات خادم Next.js مع أنماط التصميم وبناء المشروع، فقد أنشأت دورة مكثفة لك يمكنك العثور عليها هنا.
كما أن هذه المقالة متاحة أيضًا كدرس فيديو هنا:
جدول المحتويات
لماذا قد تحتاج إلى تقديم المادة الإضافية؟
عندما ننفذ عملية خادم في تسجيل النموذج، يتلقى العملية الخادمية على المعلومات التي تتم تسجيلها بشكل تلقائي. على سبيل المثال، ألقو نظرة على النموذج التالي:
<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 المنسجم، ولن تكون مكونة بالترميز. إذا فإنه أفضل أن نتعامل بالبرمجية.
المصادر
هذا كل ما لدينا لحظ الآن. هل أستمتعت بقراءة هذه المقالة وهل تعلمت شيئًا جديدًا؟ إذا كان ذلك هو حال، سأحب معرفة إن كان المحتوى مساعدًا. دعوني أشارك بعض المصادر الإضافية التي قد تحتاجوا إليها:
-
كل المصادر البرمجية التي تستخدم في هذه المقالة موجودة على موقعي GitHub.
-
هذه هي الوثيقة الرسمية للإجراءات الخاصة بالخوادمإذا كنت تريد قراءة أكثر.
-
ويمكنك قراءة ما يحتاج بشأن الالكيان المرشد هنا.
بالإضافة إلى ذلك، يمكنك الاتصال بي عن طريق:
-
التسجيل في قناتي على YouTube الخاصة بي. إذا كنت من المستعدين لتعلم
React
وبيئتها الاقتصادية، مثلNext.js
، بالمبادئ الأساسية والمشاريع، لدي أخبار جيدة لك: يمكنك البحث عن هذه القائمة التدريبية على قناتي على YouTube مع 25+ محادثة تعليمية وأكثر من 15 ساعة من المحتوى المشغول حتى الآن، مجانا. أتمنى أن تعجبكم بهذه المحتويات أيضًا. -
تتبعوني عبر X (Twitter) أو LinkedIn إذا لم تريد أن تفوت القدر من النصيحة اليومية للتعلم المتقدم.
-
البحث عن وتتبع عملي المفتوح المصدر على GitHub.
-
أنا أنشر بارحالة من المنشورات المعنية على مدونتي GreenRoots Blog، قد تجدوا أنها مفيدة أيضًا.
سأراكم قريبًا بمقالتي القادمة. حتى ذلك الحين، أتمنى لكم أن تهتموا بالنفسيات، وتواصلوا بالتعلم.
Source:
https://www.freecodecamp.org/news/how-to-pass-additional-arguments-to-nextjs-server-actions/