انتقل إلى محتوى الدرس
الدرس 22
دورة ReactJS

حقول الإدخال المحكومة وإرسال النماذج في ReactControlled Text Inputs and Form Submission

أتقن بناء حقول الإدخال النصية ومساحات الكتابة المحكومة بالحالة في React، واربط التسميات التوضيحية بخطاف useId القياسي مع معالجة إرسال النماذج وتنظيف المدخلات.
أقسام الدرس
6
الأمثلة
5
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

في صفحات HTML التقليدية، يحتفظ كل عنصر نموذج مثل <input> بنصه الداخلي الخاص داخل شجرة المتصفح بمعزل عن شيفرتك. وعند بناء واجهات تفاعلية تعتمد فيها عدادات الأحرف أو معاينات البحث الفورية أو حالة زر الحفظ على النص المكتوب، يؤدي وجود ذاكرتين منفصلتين إلى تضارب القيم.

يعالج نمط الحقل المحكوم بالحالة (Controlled Component) هذه المشكلة بجعل حالة React المصدر الوحيد للحقيقة؛ إذ يقرأ الحقل قيمته من خاصية value، وتصب كل ضغطة مفتاح في تحديث تلك الحالة.

HTML
function BadgeDesigner() {
  const [label, setLabel] = useState('UI Engineer');
  return (
    <div className="card">
      <input
        value={label}
        onChange={(e) => setLabel(e.target.value)}
      />
      <p>Live Badge: {label || 'Untitled'}</p>
    </div>
  );
}

لربط حقل نصي بنظافة، اجمع دائماً بين خاصيتين متلازمتين: value={text} لقراءة الحالة، وonChange={(e) => setText(e.target.value)} لتحديثها. في React ينطلق حدث onChange مع كل ضغطة مفتاح أو عملية لصق فوراً دون انتظار مغادرة الحقل.

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

HTML
function CouponInput() {
  const [code, setCode] = useState('SAVE20');
  function handleChange(e) {
    setCode(e.target.value.toUpperCase());
  }
  return (
    <label>
      Promo Code:
      <input value={code} onChange={handleChange} />
    </label>
  );
}

في لغة HTML القياسية يُوضع النص الابتدائي لعنصر <textarea> بين وسمي البداية والنهاية. أما في React فقد وُحّدت واجهته ليعمل بنفس أسلوب <input> تماماً؛ إذ يُكتب كوسم ذاتي الإغلاق ويستقبل نصه عبر خاصية value مع onChange.

يمنحك هذا التوحيد مرونة عالية لتحويل أي حقل سطر واحد إلى مساحة ملاحظات متعددة الأسطر دون تغيير سطر واحد في منطق الحالة.

مخطط من 4 مراحل لدورة الحقل المحكوم في React: ضغطة المستخدم ثم تحديث الحالة ثم إعادة التصيير ثم إرسال النموذج وتصفيره
HTML
function SummaryEditor() {
  const [bio, setBio] = useState('Building clean UIs.');
  return (
    <div>
      <textarea rows={3} value={bio}
        onChange={(e) => setBio(e.target.value)} />
      <p>{140 - bio.length} chars remaining</p>
    </div>
  );
}

يحتاج كل حقل نموذج متاح لذوي الإعاقة إلى عنصر <label> مرتبط عبر خاصية htmlFor بمعرّف الحقل id. غير أن كتابة معرّف ثابت مثل id="email" داخل مكون قابل لإعادة الاستخدام يفسد الصفحة فور عرض نسختين من المكون في نفس الشاشة.

يوفر خطاف useId() المدمج حلاً قياسياً بتوليد معرّف فريد لكل نسخة مكون دون أي تصادم، ويمكنك إلحاق لواحق وصفية به مثل `${id}-email` عند وجود عدة حقول.

HTML
function EmailField({ heading }) {
  const inputId = useId();
  const [email, setEmail] = useState('');
  return (
    <div>
      <label htmlFor={inputId}>{heading}</label>
      <input id={inputId} value={email}
        onChange={(e) => setEmail(e.target.value)} />
    </div>
  );
}

اربط منطق الإرسال دائماً بالحدث <form onSubmit={handleSubmit}> بدلاً من الاكتفاء بحدث النقر على الزر وحده؛ لأن احتواء الحقول داخل عنصر <form> مع زر type="submit" يتيح الإرسال التلقائي بضغط مفتاح Enter من لوحة المفاتيح.

ابدأ دالة المعالجة باستدعاء e.preventDefault() لمنع السلوك الافتراضي للمتصفح المتمثل في إعادة تحميل الصفحة كاملة وفقدان حالة التطبيق.

كثيراً ما يترك المستخدم مسافات فارغة في بداية النص أو نهايته قبل ضغط الإرسال؛ لذا نظّف النص عبر title.trim() داخل دالة الإرسال للتحقق من عدم فراغه، مع ترك الكتابة حرة داخل onChange حتى يتمكن المستخدم من كتابة المسافات بين الكلمات بسلاسة.

وبعد نجاح الحفظ، استدعِ دالة تحديث الحالة بنص فارغ مثل setTitle('') لتصفير الحقل فوراً واستقبال الإدخال التالي. يلخص الجدول التالي الفروق الأساسية:

الجانب الهندسيالحقل المحكوم في Reactالحقل غير المحكوم التقليدي
مصدر الحقيقة للبياناتحالة المكون عبر خاصية value={state}الذاكرة الداخلية لعقدة المتصفح
آلية التحديث اللحظيحدث onChange يستدعي دالة تحديث الحالةيحدث المتصفح قيمة الحقل داخلياً بصمت
تصفير الحقل برمجياًتمرير نص فارغ لدالة الحالة مباشرةيتطلب استدعاء أوامر DOM يدوية
التنسيق والعدادات الحيةمتاح تلقائياً في كل إعادة تصييريستلزم مستمعات أحداث وتعديلات يدوية
HTML
function QuickTaskForm() {
  const [task, setTask] = useState('');
  const [items, setItems] = useState(['Learn useId']);
  function handleSubmit(e) {
    e.preventDefault();
    if (!task.trim()) return;
    setItems([...items, task.trim()]);
    setTask('');
  }
  return <form onSubmit={handleSubmit}>...</form>;
}
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

تعلمت في هذا الدرس بناء الحقول النصية ومساحات الكتابة المحكومة بالحالة كمصدر وحيد للحقيقة، وربط التسميات التوضيحية بأمان عبر خطاف useId، ومعالجة إرسال النماذج بحدث onSubmit مع تنظيف النص وتصفير الحقول. الخطوة التالية: انتقل الآن إلى الدرس رقم 23 «التعامل مع القوائم المنسدلة وخانات الاختيار في React» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 Controlled Component المكون المحكوم بالحالة
عنصر نموذج تستمد قيمته المعروضة من حالة React حصراً وتتحدث عبر معالج الحدث onChange.
للمراجعة
02 Single Source of Truth المصدر الوحيد للحقيقة
الاحتفاظ بكل معلومة متغيرة في متغير حالة واحد معتمد بدلاً من تشتيتها بين المتصفح والمكون.
للمراجعة
03 useId Hook خطاف useId
خطاف مدمج في React يولد معرّفات نصية فريدة لربط عناصر التسمية والوصف بالحقول دون تصادم.
للمراجعة
04 Form Submission إرسال النموذج
استقبال حدث onSubmit على عنصر النموذج مع منع إعادة تحميل الصفحة لمعالجة البيانات برمجياً بسلاسة.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 SSR SSR
Server-Side Rendering
تصيير مكونات React على الخادم أولاً حيث يضمن خطاف useId تطابق المعرّفات مع المتصفح.
للمراجعة
02 A11Y A11Y
Accessibility
تصميم النماذج والواجهات بربط سليم للتسميات بحيث يسهل استخدامها بلوحة المفاتيح وقارئات الشاشة.
للمراجعة
03 DOM DOM
Document Object Model
شجرة عناصر المتصفح التي تزامن React خاصية القيمة فيها مع الحالة عند كل تصيير.
للمراجعة
04 SPA SPA
Single-Page Application
تطبيق صفحة واحدة يحافظ فيه منع السلوك الافتراضي للنموذج على بقاء الحالة دون إعادة تحميل.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. افتح مثال EmailField في محرر التجريب واشتق معرّفاً ثانياً لحقل اسم المستخدم وتأكد من انتقال التركيز عند النقر على التسمية.

  2. افتح مثال QuickTaskForm وجرب إدخال مسافات فارغة فقط للتحقق من الحماية ثم أضف مهمة صحيحة وراقب تصفير الحقل.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

10أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي10 أسئلة تنتظرك
01

ما الذي يجعل عنصر الإدخال input مكوناً محكوماً بالحالة في React؟

يستمد الحقل المحكوم قيمته المعروضة من متغير حالة React ويحدثها عبر معالج onChange.

02

تمرير value={name} لحقل إدخال دون توفير معالج onChange أو خاصية readOnly يجعل الحقل غير قابل للتحرير ويظهر تحذيراً في المتصفح.

صواب؛ تنبهك React لأن الحقل محكوم بقيمة ثابتة لا يستطيع المستخدم تغييرها.

03

كيف تتحكم في النص المعروض داخل عنصر textarea في معيار React الحديث؟

يستخدم عنصر textarea خاصيتي value وonChange بنفس طريقة حقل الإدخال النصي.

04

لماذا ينبغي للمكون القابل لإعادة الاستخدام توليد المعرّف بخطاف useId بدلاً من كتابة id="email" ثابت؟

تكرار المكون بمعرّف ثابت ينشئ معرّفات مكررة غير صالحة في الصفحة ويفسد ربط التسميات بالحقول.

05

يوصي التوثيق الرسمي باستخدام خطاف useId لتوليد قيم خاصية key لعناصر القوائم.

خطأ؛ يجب اشتقاق مفاتيح القوائم من البيانات نفسها بينما يقتصر useId على سمات الإتاحة.

06

لماذا يُفضّل ربط معالجة الإرسال بحدث onSubmit على عنصر form بدلاً من الاكتفاء بحدث النقر على الزر؟

يدعم حدث onSubmit الإرسال التلقائي بضغط مفتاح Enter من لوحة المفاتيح ويحسن إتاحة النموذج.

07

ماذا يحدث إذا وُضع زر مسح ثانوي داخل عنصر form دون تحديد سمة type له؟

النوع الافتراضي لأي زر داخل النموذج هو submit مما يجعله يرسل النموذج بالخطأ عند النقر عليه.

08

كيف تعيد ضبط الحقل النصي المحكوم ليفرغ تماماً عقب نجاح إرسال النموذج؟

استدعاء دالة تحديث الحالة بنص فارغ يعيد تصيير الحقل بقيمة فارغة بنظافة.

09

ينطلق معالج الحدث onChange لحقول الإدخال في React فور كتابة كل حرف دون انتظار مغادرة الحقل.

صواب؛ توحد React حدث التغيير لينطلق مع كل تعديل لحظي فتظل الحالة متزامنة فوراً.

10

لماذا يُنصح باستدعاء دالة trim عند الإرسال أو الفحص بدلاً من تطبيقها قسراً في كل ضغطة داخل onChange؟

قص المسافة النهائية في كل ضغطة مفتاح يمنع المستخدم من كتابة المسافة الفاصلة بين الكلمات أثناء الكتابة.