
كتبه كريستوفر سيلبيك ، بالتعاون مع كارولين أودن . بناءً على محاضرة بنفس الاسم ونفس الأشخاص في اجتماع ReactJS في أوسلو في يونيو 2019.
من المترجم - لا يشير الاسم الأصلي لوصايا المكونات العشر إلى React ، لكن معظم الأمثلة والتوصيات تتعلق بالتحديد برد الفعل ، بالإضافة إلى ذلك ، تم وضع المقالة تحت علامة رد الفعل وكتب المطورون رد الفعل .
ليس من السهل إنشاء مكونات يستخدمها العديد من المطورين. يجب عليك التفكير بعناية في الدعائم التي يجب استخدامها إذا كانت هذه الدعائم جزءًا من واجهة برمجة التطبيقات العامة.
في هذه المقالة ، سنقدم مقدمة موجزة لبعض أفضل الممارسات لتطوير واجهة برمجة التطبيقات (API) ككل ، وكذلك نموذج الوصايا العشر التي يمكنك استخدامها لإنشاء مكونات يسعد زملائك المطورين باستخدامها.

ما هو API؟
واجهة برمجة التطبيقات - أو واجهة برمجة التطبيقات - هي المكان الذي تلتقي فيه قطعتان من التعليمات البرمجية. هذا هو سطح الاتصال بين الرمز الخاص بك وبقية العالم. نحن نسمي هذا السطح واجهة. هذه مجموعة محددة من الإجراءات أو نقاط البيانات التي يمكنك التفاعل معها.
الواجهة بين الفصل والرمز الذي يستدعي هذه الفئة هي أيضًا واجهة برمجة تطبيقات. يمكنك استدعاء أساليب الفصل لاستلام البيانات أو تشغيل الوظائف المرفقة فيها.
باتباع نفس المبدأ ، الدعائم التي يقبلها المكون الخاص بك ، هذا هو API الخاص به . هذه هي الطريقة التي يتفاعل المطورين مع المكون الخاص بك.
بعض أفضل ممارسات تصميم API
لذلك ، ما هي القواعد والاعتبارات التي تنطبق عند تطوير API؟ حسنًا ، لقد أجرينا بعض الأبحاث ، واتضح أن هناك الكثير من الموارد الكبيرة حول هذا الموضوع. اخترنا اثنين - جوش تاوبر - "ما الذي يجعل API جيدة؟" ومقال رون كورير يحمل نفس العنوان - وجاء إلى هذه الممارسات الأربعة.
إصدارات مستقرة
أحد أهم الأشياء التي يجب مراعاتها عند إنشاء واجهة برمجة التطبيقات هو الحفاظ على ثباتها قدر الإمكان. يجب أن يكون عدد التغييرات الهامة في حده الأدنى. إذا كان عليك إجراء تغييرات مهمة ، فتأكد من كتابة أدلة تحديث تفصيلية ، وإذا أمكن ، قم بكتابة رمز تعديل يقوم بأتمتة هذه العملية للمطورين.
رسائل خطأ وصفية
كلما حدث خطأ عند الاتصال بواجهة برمجة التطبيقات ، يجب أن تفعل كل شيء ممكن لشرح الخطأ الذي حدث وكيفية إصلاحه. إذا قمت بتوبيخ المستخدم برسائل مثل "سوء الاستخدام" ولم تقدم أي تفسير ، فسوف تترك واجهة برمجة التطبيقات لديك انطباعًا سيئًا.
بدلاً من ذلك ، اكتب أخطاء وصفية تساعد المستخدم على إصلاح كيفية استخدام API الخاص بك.
تقليل المفاجآت للمطورين
المطورون هم كائنات هشة ، ويجب ألا تخيفهم عندما يستخدمون واجهة برمجة التطبيقات. بمعنى آخر ، اجعل واجهة برمجة التطبيقات سهلة الاستخدام قدر الإمكان. ستحقق ذلك إذا اتبعت أفضل الممارسات واتفاقيات التسمية الحالية.
أيضًا ، يجب أن يكون رمزك ثابتًا دائمًا. إذا كنت تستخدم الأسماء المنطقية للخصائص أو has
في مكان واحد ، ولكن تخطيها أكثر ، فإن ذلك سيشوش الناس.
تقليل API السطح
يحتاج API الخاص بك أيضًا إلى الحد الأدنى. هناك الكثير من الميزات الرائعة ، ولكن كلما كانت مساحة واجهة API الخاصة بك (واجهة API) أصغر ، سيكون على المطورين الأقل دراستها من أجل البدء في العمل بها بشكل منتج. بفضل هذا ، سيتم اعتبار واجهة برمجة التطبيقات الخاصة بك سهلة الاستخدام!
هناك دائمًا طريقة للتحكم في حجم واجهات برمجة التطبيقات. واحد منهم هو إعادة بيع واجهة برمجة التطبيقات الجديدة من القديم.
الوصايا العشر لمكونات الويب

إذن ، هذه القواعد الذهبية الأربع تعمل بشكل جيد مع واجهة برمجة تطبيقات REST والمقالات الإجرائية القديمة على Pascal - لكن كيف يمكن نقلها إلى عالم React الحديث؟
كما قلنا سابقًا ، للمكونات واجهة برمجة تطبيقات خاصة بها. نحن ندعو لهم props
، props
يتم نقل البيانات إلى المكونات. كيف يمكننا بناء الدعائم حتى لا تنتهك أي من القواعد المذكورة أعلاه؟
لقد أنشأنا هذه القائمة المكونة من عشر قواعد ذهبية يتم اتباعها بشكل أفضل عند إنشاء مكوناتك. نأمل أن تكون مفيدة لك.
1. توثيق استخدام المكونات
إذا لم يتم توثيق الطريقة التي تريد بها استخدام المكون الخاص بك ، فهذا المكون غير مجدي. حسنًا ، عديمة الجدوى تقريبًا ، يمكنك دائمًا النظر في تنفيذه ، لكن قلة من الناس تحب القيام بذلك.
هناك العديد من الطرق لتوثيق مكوناتك ، لكننا نوصيك بالاهتمام بهذه العناصر الثلاثة:
يمنحك الأولان مكانًا للعمل عند تطوير المكونات الخاصة بك ، والثالث يسمح لك بكتابة الوثائق في شكل حر باستخدام MDX
بغض النظر عن اختيارك ، قم دائمًا بتوثيق واجهة برمجة التطبيقات نفسها وكيفية وتوقيت استخدام مكوناتك . الجزء الأخير مهم في مكتبات الأغراض العامة - لكي يستخدم الأشخاص بشكل صحيح زر أو شبكة تخطيط في سياق معين.
2. تمكين دلالات السياق
HTML هي لغة لتنظيم المعلومات بطريقة دلالات. هنا فقط ، تتكون معظم <div />
علامات <div />
. هذا منطقي - لا يمكن أن تعرف المكونات العالمية مسبقًا ما ستكون عليه ، ربما <article />
، أو <section />
، أو <aside />
- ولكن هذا الموقف بعيد عن أن يكون مثاليًا.
هناك خيار آخر ، فقط دع مكوناتك تقبل prop as
، وبالتالي حدد أي عنصر DOM سيتم تقديمه. فيما يلي مثال عن كيفية تنفيذ هذا:
function Grid({ as: Element, ...props }) { return <Element className="grid" {...props} /> } Grid.defaultProps = { as: 'div', };
نعيد تسمية prop as
متغير Element
ونستخدمه في JSX الخاص بنا. نعطي قيمة div
افتراضية شائعة إذا لم يكن لدينا علامة HTML أكثر دلالة لتمريرها.
عندما يحين الوقت لاستخدام مكون <Grid />
، يمكنك ببساطة تمرير العلامة الصحيحة:
function App() { return ( <Grid as="main"> <MoreContent /> </Grid> ); }
هذا يعمل أيضا مع مكونات React. على سبيل المثال ، إذا كنت تريد المكون <Button />
تقديم React Router <Link />
:
<Button as={Link} to="/profile"> Go to Profile </Button>
3. تجنب الدعائم المنطقية
الدعائم المنطقية هي ، مثل ، فكرة جيدة. يمكن استخدامها بدون قيمة ، لذلك تبدو أنيقة للغاية:
<Button large>BUY NOW!</Button>
ولكن على الرغم من أنها تبدو لطيفة ، إلا أن الخصائص المنطقية تسمح بإمكانيات اثنين فقط. أو خارجها مرئية أو خفية. 1 أو 0.
كلما بدأت في تقديم خصائص منطقية لأشياء مثل الحجم أو الخيارات أو الألوان أو أي شيء يمكن أن يكون أي شيء آخر غير الاختيار الثنائي ، فأنت تواجه مشكلات.
<Button large small primary disabled secondary> ?? </Button>
بمعنى آخر ، الخصائص المنطقية في كثير من الأحيان لا تتناسب مع المتطلبات المتغيرة. بدلاً من ذلك ، بالنسبة للقيم التي قد تصبح شيئًا آخر غير التحديد الثنائي ، من الأفضل استخدام القيم المذكورة ، مثل السلاسل.
<Button variant="primary" size="large"> </Button>
هذا لا يعني أنه لا يمكن استخدام الخصائص المنطقية على الإطلاق. يمكنك! يجب أن تظل الدعامة disabled
، التي ذكرتها أعلاه ، منطقية - لأنه لا توجد حالة وسط بين التشغيل والإيقاف. مجرد ترك الخصائص المنطقية فقط لاختيار ثنائي حقا.
4. استخدام props.children
React له بعض الخصائص الخاصة التي يتم التعامل معها بشكل مختلف عن غيرها. هناك حاجة إلى أحد هذه key
لتتبع ترتيب عناصر القائمة. وآخر دعامة خاصة من هذا القبيل هي children
.
يتم وضع كل ما تضعه بين علامة props.children
داخل props.children
. ويجب عليك استخدام هذا كلما كان ذلك ممكنا.
لماذا؟ لأنه أسهل بكثير من وجود content
دعم content
أو شيء من هذا القبيل عادة ما يستغرق فقط قيم بسيطة ، مثل النص.
<TableCell content="Some text" /> // <TableCell>Some text</TableCell>
هناك العديد من المزايا لاستخدام props.children
. أولاً ، هذا مشابه لكيفية عمل HTML العادي. ثانيا ، يمكنك نقل بحرية ما تريد! بدلاً من إضافة الدعائم مثل leftIcon
و rightIcon
إلى المكون الخاص بك - ما عليك سوى تمريرها كجزء من props.children
:
<TableCell> <ImportantIcon /> Some text </TableCell>
قد تقول أن المكون الخاص بك يحتاج فقط إلى تقديم نص عادي ، وفي بعض الحالات يكون كذلك. حتى بعض نقطة. باستخدام props.children
، فإنك تضمن أن API الخاص بك سيكون جاهزًا لتغيير المتطلبات.
5. دع الوالد يتشبث بالمنطق الداخلي
في بعض الأحيان نقوم بإنشاء مكونات تحتوي على الكثير من المنطق والحالات الداخلية - على سبيل المثال ، الإكمال التلقائي أو المخططات التفاعلية.
غالبًا ما تعاني هذه المكونات من واجهات برمجة التطبيقات المفرطة ، ومن أسباب ذلك العدد الكبير لحالات الاستخدام المختلفة التي تتراكم مع تطور المشروع.
ولكن ماذا لو استطعنا توفير دعامة واحدة موحدة تسمح للمطور بالتحكم في السلوك الافتراضي للمكون أو الاستجابة له أو ببساطة تغييره؟
كتب Kent Dodds مقالة ممتازة عن مفهوم مخفضات الحالة. هنا مقال عن المفهوم نفسه ، وهنا أيضًا مقال حول كيفية تطبيق هذا على علاقات React .
باختصار ، هذا هو نمط نقل وظيفة مخفض الحالة إلى المكون الخاص بك ، مما سيتيح للمطور الوصول إلى جميع الإجراءات المنفذة داخل المكون الخاص بك. يمكنك تغيير الحالة أو حتى التسبب في آثار جانبية. هذه طريقة رائعة لتوفير مستوى عالٍ من التخصيص ، دون أي دعائم .
إليك ما قد يبدو عليه:
function MyCustomDropdown(props) { const stateReducer = (state, action) => { if (action.type === Dropdown.actions.CLOSE) { buttonRef.current.focus(); } }; return ( <> <Dropdown stateReducer={stateReducer} {...props} /> <Button ref={buttonRef}>Open</Button> </> }
بالمناسبة ، يمكنك إنشاء طرق أبسط للرد على الأحداث. من onClose
أن يؤدي استخدام onClose
في المثال السابق إلى جعل استخدام المكون أكثر ملاءمة. استخدم نمط "مخفض الحالة" عند الحاجة.
6. استخدام عامل الانتشار للحصول على الدعائم المتبقية
في كل مرة تقوم فيها بإنشاء مكون جديد ، تأكد من تطبيق علامة القطع على الدعائم المتبقية وإرسالها إلى العنصر الذي يجعل هذا الأمر منطقيًا.
لا تحتاج إلى متابعة إضافة الدعائم إلى المكون الخاص بك ، والذي سيتم ببساطة تمريره إلى المكون الأساسي أو العنصر. سيؤدي ذلك إلى جعل API أكثر استقرارًا عن طريق التخلص من الحاجة إلى العديد من أخطاء الإصدارات الصغيرة عندما يحتاج المطور التالي إلى مستمع حدث جديد أو علامة ARIA.
يمكنك القيام بذلك مثل هذا:
function ToolTip({ isVisible, ...rest }) { return isVisible ? <span role="tooltip" {...rest} /> : null; }
عندما ينتقل مكونك إلى تطبيقك ، مثل اسم فئة أو معالج onClick
، تأكد من أن مطورًا آخر يمكنه القيام بنفس الشيء. في حالة فئة ما ، يمكنك ببساطة إضافة فئة prop باستخدام مكتبة أسماء npm المناسبة (أو مجرد تسلسل السلسلة):
import classNames from 'classnames'; function ToolTip(props) { return ( <span {...props} className={classNames('tooltip', props.tooltip)} /> }
في حالة معالجات النقرات وعمليات الاسترجاعات الأخرى ، يمكنك دمجها في وظيفة واحدة باستخدام أداة مساعدة صغيرة. فيما يلي طريقة واحدة للقيام بذلك:
function combine(...functions) { return (...args) => functions .filter(func => typeof func === 'function') .forEach(func => func(...args)); }
هنا نقوم بإنشاء دالة تقبل قائمة الوظائف لدمجها. تقوم بإرجاع رد اتصال جديد ، والذي يستدعي كل منهم بدوره بنفس الحجج.
هذه الوظيفة يمكن استخدامها بهذه الطريقة:
function ToolTip(props) { const [isVisible, setVisible] = React.useState(false); return ( <span {...props} className={classNames('tooltip', props.className)} onMouseIn={combine(() => setVisible(true), props.onMouseIn)} onMouseOut={combine(() => setVisible(false), props.onMouseOut)} /> ); }
7. استخدم القيم الافتراضية
تأكد من إعطاء افتراضات كافية (الافتراضيات) إلى الدعائم الخاصة بك. وبالتالي ، سوف تقلل من عدد الدعائم الإلزامية. هذا سوف تبسيط API الخاص بك إلى حد كبير.
خذ ، على سبيل المثال ، معالج onClick
. إذا لم يكن الكود الخاص بك بحاجة إلى هذا المعالج ، فاستخدم الدالة الفارغة (noop-function) كدعم افتراضي. بهذه الطريقة يمكنك أن تسميها في الكود الخاص بك كما لو كانت مرت دائما.
مثال آخر قد يكون لإدخال المستخدم. افترض أن سلسلة الإدخال عبارة عن سلسلة فارغة ما لم يتم تحديد خلاف ذلك. سيتيح لك ذلك التأكد من أنك تتعامل دائمًا مع كائن سلسلة ، وليس شيئًا غير معرف أو فارغ.
8. لا حاجة لإعادة تسمية سمات HTML
HTML كلغة لها دعائم خاصة بها - أو سمات ، وهي بحد ذاتها واجهة برمجة تطبيقات لعناصر HTML. فلماذا لا تستمر في استخدام واجهة برمجة التطبيقات هذه؟
كما ذكرنا سابقًا ، يعد تقليل سطح واجهة برمجة التطبيقات وإدراكها من الطرق المفيدة لتحسين واجهة برمجة التطبيقات لمكوناتك. لذا بدلاً من إنشاء screenReaderLabel
prop الخاص بك ، فلماذا لا تستخدم علامة aria-label
حالية فقط؟
الابتعاد عن إعادة تسمية أي سمات HTML الموجودة لديك "سهولة الاستخدام". حتى أنك لا تحل محل واجهة برمجة التطبيقات الحالية - يمكنك ببساطة إضافة واجهة المستخدم الخاصة بك. لا يزال بإمكان الناس اجتياز aria-label
مع شاشتك ReeaderLabel - وما هي القيمة النهائية إذن؟
تأكد أيضًا من عدم تجاوز سمات HTML في مكوناتك. مثال رائع هو السمة type
للعنصر <button />
. يمكن أن يكون submit
(الافتراضي) ، button
أو reset
. ومع ذلك ، فإن العديد من المطورين يعيدون تعريف هذه الدعامة للإشارة إلى النوع المرئي للزر ( primary
، cta
، إلخ).
إذا كنت ستستخدم مثل هذا prop ، فستحتاج إلى إضافة تخطي لسمة type
الحقيقية. سيؤدي ذلك إلى الارتباك والشك والانزعاج من جانب المطورين.
صدقني - لقد ارتكبت هذا الخطأ مرارًا وتكرارًا - إذا ارتكبت ذلك ، فستضطر إلى فك الارتباط لفترة طويلة.
9. اكتب أنواع الدعائم (أو مجرد أنواع)
لن تكون المستندات جيدة مثل الوثائق التي تعيش داخل الكود. React يأتي مع وسيلة رائعة لإعلان واجهات برمجة التطبيقات الخاصة بك باستخدام حزمة prop-types
. استخدمه
يمكنك تحديد أي متطلبات تنسيق للدعائم الإلزامية والاختيارية ، ويمكنك تحسينها من خلال تعليقات JSDoc .
إذا لم تحدد الدعائم الإلزامية أو تجاوزت قيمة غير صالحة أو غير متوقعة ، فستتلقى في وقت التشغيل تحذيرًا في وحدة التحكم. هذا يساعد كثيرا أثناء التطوير ، ويمكن إزالته من الإنتاج.
إذا قمت بكتابة تطبيقات React الخاصة بك في TypeScript أو باستخدام Flow ، فستحصل على وثائق API كدالة لغة. هذا يعزز كذلك دعم أدوات التطوير ويبسط العمل.
إذا كنت لا تستخدم جافا سكريبت المكتوبة ، فلا يزال عليك التفكير في تقديم تعريفات النوع لهؤلاء المطورين الذين يستخدمونها. بعد ذلك سيكون من الأسهل عليهم استخدام مكوناتك.
10. تصميم للمطورين
وأخيرا ، فإن أهم قاعدة لمتابعة. تأكد من تحسين واجهة برمجة التطبيقات والعمل مع المكونات الخاصة بك للمطورين الذين سيستخدمونها.
إحدى طرق تبسيط عمل مطور البرامج هي إعطائه ملاحظات حول الاستخدام غير المناسب. قم بذلك مع رسائل الخطأ وأيضًا ولكن أثناء التطوير فقط ، مع التحذيرات من وجود طرق أكثر فاعلية لاستخدام المكون الخاص بك.
عند كتابة الأخطاء والتحذيرات ، قم بتقديم روابط إلى مستنداتك أو أظهر أمثلة بسيطة على الكود. وكلما أسرع المطور في فهم ماهية المشكلة وكيفية حلها ، كلما كان المكوّن لديك أكثر ملاءمة للعمل.
بشكل لا يصدق ، ولكن كما تبين لاحقًا ، لا يؤثر وجود كل هذه التحذيرات الطويلة في الخطأ على حجم الحزمة النهائية. بفضل معجزات إزالة الكود الميت ، يمكن إزالة كل هذا النص ورمز الخطأ أثناء التجميع في الإنتاج.
واحدة من المكتبات التي تعطي ردود فعل جيدة بشكل لا يصدق هي React نفسها. لا يهم إذا نسيت تحديد مفتاح عناصر القائمة ، أو كتبت طريقة دورة الحياة بطريقة غير صحيحة ، أو ربما نسيت تمديد الفئة الأساسية أو اتصلت بالشبك بطريقة غير مؤكدة - على أي حال ، سوف تحصل على رسائل خطأ كبيرة في وحدة التحكم. لماذا يجب على المطورين الذين يستخدمون مكوناتك أن يتوقعوا منك أقل؟
لذلك تصميم للمستخدمين في المستقبل. تصميم لنفسك من المستقبل. صمم للاسف الذي سيتعين عليه الحفاظ على الكود عند المغادرة! تصميم للمطورين.
في المجموع
يمكننا أن نتعلم الكثير من طريقة API الكلاسيكية. باتباع النصائح والحيل والقواعد والوصايا الواردة في هذه المقالة ، يمكنك إنشاء مكونات سهلة الاستخدام وسهلة الصيانة وبديهية ومرنة للغاية إذا لزم الأمر.