كتابة واجهة برمجة تطبيقات لمكونات React ، الجزء 1: لا تقم بإنشاء الدعائم المتعارضة
كتابة واجهة برمجة تطبيقات لمكونات التفاعل ، الجزء 2: إعطاء أسماء للسلوك ، وليس التفاعل
كتابة واجهة برمجة تطبيقات لمكونات React ، الجزء 3: ترتيب الدعائم هو المهم
كتابة واجهة برمجة تطبيقات لمكونات التفاعل ، الجزء 4: احذر من Apropacalypse!
كتابة واجهة برمجة تطبيقات لمكونات التفاعل ، الجزء 5: مجرد استخدام التكوين
نكتب واجهة برمجة التطبيقات لمكونات React ، الجزء 6: نخلق التواصل بين المكونات
لدينا عنصر التبديل - Switch
، والذي يقبل prop ، دعونا نسميها something
الوقت الحالي.
يمكن للمطور الذي يستخدم المكون الخاص بنا تمرير وظيفة ، وسنسميها عندما تتغير القيمة.

<Switch something={fn} />
يمنحك clickHandler
القدرة على استدعاء prop كما نود: handler
/ clickHandler
/ onClick
/ onToggle
، إلخ.
أصبحت الاتفاقية التي يجب أن يبدأ اسم معالج الأحداث on
، على سبيل المثال ، onClick
، onClick
. هذا لأن مواصفات HTML بها الكثير من المعالجات التي تتبع هذه الاتفاقية بالفعل: onkeydown
، onkeydown
، onclick
، إلخ.
إعادة استخدام اتفاقية موجودة هي فكرة رائعة ؛ لن يتعين على المطورين تذكر شيء جديد.
حسنا ، ماذا عن onClick
؟
<Switch onClick={fn} />
أنا لست مؤيدًا للاسم onClick
، يشير هذا الاسم إلى أن النقر بالماوس هو الطريقة الوحيدة للتفاعل مع هذا المكون.
يمكن للمستخدمين على جهاز محمول الضغط على المفتاح بإصبع أو سحبه إلى اليمين. يمكن للمستخدمين ضعاف البصر استخدامها مع برنامج قارئ الشاشة واستخدام مفاتيح لوحة المفاتيح.
كمطور يستخدم هذا المكون ، لا أريد التفكير في كيفية تفاعل المستخدمين النهائيين مع هذا المكون. أريد فقط إرفاق دالة تسمى عندما تتغير القيمة.
أعط أسماء لواجهة برمجة التطبيقات الخاصة بك والتي لن تشير إلى طريقة للتفاعل:
<Switch onToggle={fn} />
هذا منطقي ، أليس كذلك؟ تبديل toggles
(تبديل) بين قيمتين.
داخل أحد المكونات ، قد تحتاج إلى وكيل لجميع التفاعلات الممكنة في نفس الوظيفة
function Switch(props) { return ( <div className="switch" /* */ onClick={props.onToggle} onKeyDown={function(event) { /* enter , event */ if (event.key === 'Enter') props.onToggle(event) }} onDrag={function(event) { /* */ if (event.toElement === rightSide) props.onToggle(event) }} /> ) }
أخذنا في الاعتبار جميع الخيارات لإعطاء API واضحة لمستخدمينا (المطورين).
الآن دعنا نتحدث عن مكون إدخال النص.

<TextInput />
HTML له سمة onchange ، وثائق onChange
تستخدم onChange
في الأمثلة. على ما يبدو ، هناك إجماع على هذه النتيجة.
<TextInput onChange={fn} />
بسيط جدا
الآن دعونا نضع كلا المكونين جنبًا إلى جنب.

<TextInput onChange={fn} /> <Switch onToggle={fn} />
ترى شيئا غريبا؟
على الرغم من حقيقة أن كلا المكونين يتطلبان نفس السلوك ، إلا أن prop تُسمى بطريقة مختلفة. هذه الدعائم مثالية للمكونات الخاصة بكل منها ، ولكن عندما تنظر إلى مكوناتك معًا ، فإنها تبدو مثيرة للجدل إلى حد كبير.
يجب على المطور الذي سيستخدم هذه المكونات دائمًا التحقق من اسم prop قبل استخدامه.
حتى هنا هو نصيحة رقم 2: نسعى جاهدين من أجل الدعائم متسقة بين المكونات . يجب أن يكون نفس السلوك دعم كافة المكونات.
يمكن أيضًا صياغة هذه النصيحة على النحو التالي: السعي للحصول على الحد الأدنى من مساحة واجهة برمجة التطبيقات . يجب أن تحد من عدد واجهات برمجة التطبيقات التي يجب على المطور السيطرة عليها قبل أن يتمكن من العمل بشكل منتج.
أريد أن أقول إن كل المزايا في هذا الموضوع تذهب إلى سيباستيان ماركباج . (عرضه التقديمي: الحد الأدنى لمساحة API )
طريقة تنفيذ هذه النصيحة هي اختيار دعامة واحدة واستخدامها في جميع مكوناتك. من بين اثنين من الدعائم التي لدينا في مثالنا ، onChange
أيضا في مواصفات HTML ، لذلك قد يتعرف بعض المطورين عليه.

<TextInput onChange={fn} /> <Switch onChange={fn} /> <Select onChange={fn} /> // etc.
إن الاتساق بين المكونات ، ونتيجة لذلك ، بساطة تعلم واجهة برمجة التطبيقات الخاصة بك ، يفوق اختيار الدعامة "المثالية" للمكون الفردي.
مكافأة صغيرة.
دعونا نتحدث عن توقيع هذه الوظيفة.
<TextInput onChange={fn} />
يتلقى onChange
أحداث onChange
( fn
في هذا المثال) وسيطة واحدة - event
.
إنه يعمل مع كل تغيير. يمكنك الحصول على مجموعة من المعلومات المفيدة من هذا الحدث.
function fn(event) { console.log(event.target)
على الأرجح ، سيكون معظم المطورين مهتمين بـ event.target.value
، حتى يتمكنوا من استخدامه لبعض المهام الأخرى - الاستخدام في الولاية أو إرسال النموذج أو ما إلى ذلك.
في حالة مكون Switch
، يمثل كل إجراء "حدث" منفصل - event
. سيكون لهذا event
خصائص مختلفة للنقر والسحب. كيف نتأكد من توافق API؟
يمكننا تعيين event.target.value
يدويًا لكل "حدث":
function Switch(props) { const fireHandler = event => { const newValue = !oldValue event.target.value = newValue props.onChange(event) } return ( <div className="switch" /* */ onClick={fireHandler} onKeyDown={function(event) { if (event.key === 'Enter') fireHandler(event) }} onDrag={function(event) { if (event.toElement === rightSide) fireHandler(event) }} /> ) }