Menu
flag Ar iconالعربيةdown icon

الأحداث في React: onClick وonChange وonSubmit وغيرها

أحداث React هي props مثل onClick وonChange تأخذ دالة، تستدعيها React مع كائن حدث عندما يتصرف المستخدم. تعلّم كيف تمرر المعالج بدلًا من استدعائه، وتمرر الوسائط، وتقرأ e.target.value وe.key، وتمنع إعادة تحميل النماذج، وتوقف الانتشار.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

تتعامل React مع الأحداث عبر props تحمل اسم الحدث بنمط camelCase، مثل onClick وonChange وonSubmit. تمرر دالة، فتستدعيها React مع كائن حدث عندما ينقر المستخدم أو يكتب أو يرسل.

كل نقرة تشغّل handleClick، التي تحدّث العدد وتسجّل في وحدة التحكم أسفل المعاينة. جرّب onDoubleClick مكان onClick: الآن لا يُحسب إلا النقر المزدوج.

مرّر الدالة ولا تستدعِها

تأخذ الـ prop دالة، وتستدعيها React لاحقًا. ومن الأخطاء الشائعة جدًا إضافة قوسين، ما يستدعي الدالة فورًا، أثناء العرض، ويسلّم React قيمتها المُرجعة بدلًا منها.

تُظهر وحدة التحكم "Hi, during render" قبل أن تلمس أي شيء: شغّلت React الدالة sayHi أثناء عرض الزر الأول، ولأن sayHi تُرجع undefined فليس لذلك الزر أي معالج إطلاقًا. النقر على Wrong لا يفعل شيئًا. والنقر على Right يسجّل "Hi, Ada"، لأن الدالة السهمية لا تعمل إلا عند النقر.

الدالة السهمية هي أيضًا طريقة تمرير الوسائط. ينشئ onClick={() => removeItem(item.id)} دالة صغيرة لكل عنصر، وتستدعي تلك الدالة دالتك بالمعرّف الصحيح. إذا كان المعالج لا يأخذ وسائط، فمرّره باسمه: onClick={handleClick}.

ومع دالة ضبط الحالة يكون الخطأ أسوأ: يضبط onClick={setCount(count + 1)} الحالة أثناء العرض، فيعيد العرض، فيضبط الحالة من جديد، وتتوقف React برسالة "Too many re-renders".

كائن الحدث

تمرر React لكل معالج وسيطًا واحدًا، هو كائن الحدث. له خصائص حدث المتصفح نفسها: e.target هو العنصر الذي وقع عليه الحدث، وe.key هو المفتاح المضغوط، وe.preventDefault() يلغي الإجراء الافتراضي للمتصفح. تغلّف React الحدث الأصلي في ما تسميه حدثًا اصطناعيًا، فيتصرف بالطريقة نفسها في كل متصفح؛ والحدث الأصلي موجود في e.nativeEvent إن احتجت إليه يومًا.

أكثر ما تستخدمه هو e.target.value في onChange وe.key في onKeyDown.

اكتب hooks واضغط Enter: يُضاف الوسم ويُفرَّغ الحقل. تسجّل وحدة التحكم كل مفتاح، بما فيها Shift وBackspace وEnter، بالأسماء الموجودة في e.key. اضغط Escape في منتصف كلمة لتتخلص منها.

يُطلق onChange في React مع كل ضغطة مفتاح. في HTML العادية يُطلق الحدث change على حقل نصي فقط عندما يفقد التركيز، لذا فهذا اختلاف مقصود: يتيح للحقل والحالة أن يبقيا متوافقين حرفًا بحرف. ومربعات الاختيار تعطيك e.target.checked بدلًا من value. تتناول صفحة النماذج كل أنواع الحقول.

النماذج وpreventDefault

عندما يُرسل نموذج، يكون الإجراء الافتراضي للمتصفح هو إرساله وتحميل صفحة جديدة. في تطبيق React تريد في الغالب التعامل مع البيانات بنفسك، لذا يبدأ معالج الإرسال بـ e.preventDefault().

ضع onSubmit على <form>، لا onClick على الزر: عندها يؤدي الضغط على Enter في الحقل إلى الإرسال أيضًا، وتعمل فحوص المتصفح الخاصة (هنا required وtype="email") أولًا. احذف السطر e.preventDefault() وأرسل مرة أخرى: كانت صفحة حقيقية ستنتقل الآن إلى صفحة جديدة وتفقد رسالة الشكر. تمنع المعاينة ذلك وتعرض بدلًا منه ما كان النموذج سيرسله، email= بلا قيمة، لأن setEmail('') كانت قد فرّغت الحقل عندما قُرئ النموذج.

تتيح لك React 19 أيضًا تمرير دالة إلى <form action={fn}>، تستقبل بيانات النموذج وتعيد ضبط الحقول غير المتحكم بها نيابة عنك. تعرض صفحة النماذج الأسلوبين.

الانتشار وstopPropagation

معظم الأحداث تنتشر صعودًا: بعد أن تعمل على العنصر الذي نقرته، تعمل على أبيه، ثم على أبي أبيه، حتى القمة. تتبع معالجات React الترتيب نفسه. ولهذا تُحسب النقرة على زر داخل بطاقة قابلة للنقر نقرةً على البطاقة أيضًا.

انقر Bubbles up فتسجّل وحدة التحكم الزر، ثم اللوحة الداخلية، ثم البطاقة الخارجية. وانقر Stops here فلا يسجّل إلا الزر: ينهي e.stopPropagation() الصعود. والنقر على نص اللوحة الداخلية نفسها يسجّل اللوحة والبطاقة.

استخدم stopPropagation باعتدال. ومن الحالات المشروعة الشائعة زر حذف داخل صف قائمة قابل للنقر، حيث ينبغي ألا يفتح النقر على الحذف الصف أيضًا. إذا احتاج الأب إلى معرفة ما إذا كانت النقرة قد جاءت من ابن، فافحص e.target بدلًا من إيقاف الحدث. ولتشغيل معالج في طريق النزول بدلًا من ذلك، قبل أن يرى الأبناء الحدث، توفر React نسخ الالتقاط مثل onClickCapture.

preventDefault وstopPropagation أداتان مختلفتان. الأولى تلغي ما كان المتصفح سيفعله (اتباع رابط، أو إرسال نموذج، أو تحديد مربع اختيار). والثانية تمنع المعالجات الأخرى من سماع الحدث. استدعاء إحداهما لا يؤدي عمل الأخرى.

أحداث شائعة أخرى

يغطي النمط نفسه كل حدث تدعمه React. إليك بعض ما ستستخدمه كثيرًا:

  • يُطلق onFocus وonBlur عندما يكتسب حقل التركيز ويفقده، وهما مفيدان لإظهار التحقق بعد أن يغادر المستخدم حقلًا.
  • يُطلق onMouseEnter وonMouseLeave عندما يدخل المؤشر إلى عنصر ويخرج منه. وخلافًا لمعظم الأحداث فهما لا ينتشران، فتحريك المؤشر من أب إلى ابنه لا يطلق onMouseEnter الخاص بالأب من جديد.
  • تعمل onPointerDown وonPointerMove وonPointerUp مع الفأرة واللمس والقلم على حد سواء، ما يجعلها الخيار الأفضل للسحب.
  • يُطلق onScroll أثناء تمرير عنصر. وفي React لا ينتشر.

يستقبل كل معالج كائن حدث بالخصائص التي تناسبه: e.clientX لأحداث المؤشر، وe.key لأحداث لوحة المفاتيح، وe.target لها جميعًا.

تمرير المعالجات كـ props

يمكن للمكوّنات أن تقبل معالجات من أبيها مثل أي prop أخرى. سمّها onSomething بحسب ما حدث، وسمّ الدالة التي تعالجه handleSomething. هذا يحاكي الأحداث المدمجة ويوضح أي props هي دوال استدعاء.

لا يملك Stepper الرقم؛ بل يبلّغ عن النقرات ويقرر الأب معناها. غيّر handleDecrement ليتوقف عند 1 بدلًا من 0 فيتبعه المكوّن دون تعديله. إبقاء الحالة في الأب وتمرير المعالجات إلى الأسفل هو النمط الموصوف في رفع الحالة.

props المعالجات المخصصة مجرد أسماء. لا يفعل onIncrement على مكوّنك شيئًا حتى يمرره المكوّن إلى onClick على عنصر حقيقي، ويمكنك أن تعطيه أي وسائط تريدها، مثل onSelect(item.id).

الأسئلة الشائعة

كيف أمرر وسيطًا إلى معالج onClick؟

غلّف الاستدعاء في دالة سهمية: onClick={() => deleteItem(item.id)}. الدالة السهمية هي ما تستدعيه React عند النقر، وهي بدورها تستدعي دالتك مع الوسيط.

لماذا يعمل onClick الخاص بي عند تحميل الصفحة؟

لقد استدعيت الدالة بدلًا من تمريرها. يشغّل onClick={handleClick()} الدالة handleClick أثناء العرض ويمرر قيمتها المُرجعة. اكتب onClick={handleClick} أو onClick={() => handleClick(id)}.

ما الفرق بين onChange في React وفي HTML؟

في HTML يُطلق الحدث change على حقل نصي عندما يفقد التركيز. أما onChange في React فيُطلق مع كل ضغطة مفتاح، مثل الحدث الأصلي input، لتتبع الحالة النص أثناء كتابته.

كيف أمنع النموذج من إعادة تحميل الصفحة في React؟

استدعِ e.preventDefault() في بداية معالج onSubmit. ضع المعالج على <form>، لا على زر الإرسال، ليؤدي الضغط على Enter في أحد الحقول إلى الإرسال أيضًا.

ما هو الحدث الاصطناعي في React؟

هو كائن الحدث الذي تمرره React إلى معالجاتك. يغلّف الحدث الأصلي للمتصفح بالخصائص والتوابع نفسها (target وkey وpreventDefault() وstopPropagation()) ويتصرف بالطريقة نفسها في كل المتصفحات. والحدث الأصلي متاح على أنه e.nativeEvent.

رسم توضيحي للغات البرمجة في Coddy

تعلّم البرمجة مع Coddy

ابدأ الآن