رد فعل البرنامج التعليمي الجزء 9: خصائص المكون

في جزء اليوم من ترجمة البرنامج التعليمي React ، سنتحدث عن خصائص المكون. هذا واحد من أهم المفاهيم التي تنعكس في هذه المكتبة.

الصورة

الجزء 1: نظرة عامة على الدورة ، وأسباب شعبية React ، ReactDOM و JSX
الجزء 2: المكونات الوظيفية
الجزء 3: ملفات المكونات ، هيكل المشروع
الجزء 4: مكونات الوالدين والطفل
الجزء 5: بدء العمل في تطبيق TODO ، أساسيات التصميم
الجزء 6: حول بعض ميزات الدورة ، JSX وجافا سكريبت
الجزء 7: الأنماط المضمنة
الجزء 8: مواصلة العمل على تطبيق TODO ، الإلمام بخصائص المكونات
الجزء 9: خصائص المكون
الجزء 10: ورشة عمل حول العمل مع خصائص المكون والتصميم
الجزء 11: توليد العلامات الديناميكية وطريقة صفائف الخريطة
الجزء 12: ورشة العمل ، المرحلة الثالثة من العمل على طلب TODO
الجزء 13: المكونات القائمة على الفصل
الجزء 14: ورشة عمل حول المكونات القائمة على الفصل ، وحالة المكون
الجزء 15: ورش العمل الصحية المكونة
الجزء 16: المرحلة الرابعة من العمل على طلب TODO ، التعامل مع الأحداث
الجزء 17: المرحلة الخامسة من العمل على تطبيق TODO ، وتعديل حالة المكونات
الجزء 18: المرحلة السادسة من العمل على طلب TODO
الجزء 19: طرق دورة حياة المكون
الجزء 20: الدرس الأول في التقديم الشرطي
الجزء 21: الدرس الثاني وورشة العمل حول التقديم الشرطي
الجزء 22: المرحلة السابعة من العمل على تطبيق TODO ، وتنزيل البيانات من مصادر خارجية
الجزء 23: الدرس الأول حول العمل مع النماذج
الجزء 24: نماذج الدرس الثاني
الجزء 25: ورشة عمل حول العمل مع النماذج
الجزء 26: بنية التطبيق ، نمط الحاوية / المكون
الجزء 27: مشروع المقرر

الدرس 19. خصائص المكون في التفاعل


الأصل

قم بإنشاء مشروع جديد باستخدام تطبيق create-react-app وتغيير شفرة العديد من الملفات القياسية من مجلد src .

فيما يلي رمز ملف index.js :

 import React from "react" import ReactDOM from "react-dom" import "./index.css" import App from "./App" ReactDOM.render(<App />, document.getElementById("root")) 

فيما يلي الأنماط الموضحة في ملف index.css :

 body { margin: 0; } .contacts { display: flex; flex-wrap: wrap; } .contact-card { flex-basis: 250px; margin: 20px; } .contact-card > img { width: 100%; height: auto; } .contact-card > h3 { text-align: center; } .contact-card > p { font-size: 12px; } 

إليك الرمز الموجود في ملف App.js :

 import React from "react" function App() {   return (       <div className="contacts">           <div className="contact-card">               <img align="center" src="http://placekitten.com/300/200"/>               <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>               <p>Phone: (212) 555-1234</p>               <p>Email: mr.whiskaz@catnap.meow</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/200"/>               <h3><font color="#3AC1EF">▍Fluffykins</font></h3>               <p>Phone: (212) 555-2345</p>               <p>Email: fluff@me.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/300"/>               <h3><font color="#3AC1EF">▍Destroyer</font></h3>               <p>Phone: (212) 555-3456</p>               <p>Email: ofworlds@yahoo.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/200/100"/>               <h3><font color="#3AC1EF">▍Felix</font></h3>               <p>Phone: (212) 555-4567</p>               <p>Email: thecat@hotmail.com</p>           </div>       </div>   ) } export default App 

إليك الشكل الذي سيبدو عليه هذا التطبيق في المتصفح.


صفحة التطبيق في المتصفح

بعد تحليل الكود ومظهر التطبيق ، يمكننا أن نستنتج أنه سيكون من الجيد استخدام مكونات خاصة لعرض البطاقات مع معلومات عن الحيوانات. الآن يتم تشكيل هذه العناصر عن طريق مكون App . النظر في ما تحدثنا عنه في الفصول السابقة ، يمكنك الذهاب أبعد من ذلك - التفكير في مكون عالمي يمكن تخصيصه عن طريق تمرير سمات أو خصائص إليه.

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

 <div className="contact-card">   <img align="center" src="http://placekitten.com/300/200"/>   <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>   <p>Phone: (212) 555-1234</p>   <p>Email: mr.whiskaz@catnap.meow</p> </div> 

يعرض التطبيق أربع كتل من هذا القبيل ، يمكن استخدام كل منها لإنشاء مكون مستقل ، لكن هذا النهج لا يناسبنا. لذلك ، سنقوم بإنشاء مكون واحد سيصبح أساس جميع البطاقات المعروضة بواسطة التطبيق. للقيام بذلك ، قم بإنشاء ملف مكون جديد في مجلد src - ContactCard.js ثم ضع فيه رمزًا يُرجع العنصر <div> الأول الذي تم إرجاعه بواسطة مكون App ، والذي تم ذكر رمزه أعلاه. فيما يلي رمز مكون ContactCard :

 import React from "react" function ContactCard() {   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

من الواضح أنك إذا قمت بإنشاء عدة مثيلات لهذا المكون ، فستحتوي جميعها على نفس البيانات ، لأن هذه البيانات مشفرة في كود المكون. ونود ، عند إنشاء مثيلات مختلفة لهذا المكون ، سيكون من الممكن تخصيص البيانات المعروضة به. النقطة المهمة هي أنه يمكن تمرير المكون بعض الخصائص ، والتي يمكن استخدامها بعد ذلك.

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

 function addNumbers() {   return 1 + 1 } 

يمكن استخدامه لمعرفة مجموع الأرقام 1 و 1 ، ولكن ، على سبيل المثال ، لإضافة 1 و 2 ، باستخدام وظائف لا تقبل أي إدخال ، يجب أن نكتب وظيفة جديدة. من الواضح تمامًا أن هذا النهج سيؤدي إلى إزعاج كبير إذا كنت بحاجة إلى إضافة أرقام مختلفة ، لذلك في مثل هذه الحالة ، سيكون من الحكمة إنشاء وظيفة عالمية لإضافة أرقام ، تأخذ رقمين وتُرجع مجموعهما:

 function addNumbers(a, b) {   return a + b } 

تعتمد وظيفة هذه الوظيفة على الوسائط التي تم تمريرها إليها عند استدعائها. من خلال إنشاء مكونات React ، يمكننا أن نذهب بنفس الطريقة تمامًا.

نحن نستورد مكون App.js ContactCard أربعة من ContactCard ، دون حذف الكود الذي يشكل البطاقات في صفحة التطبيق الآن:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard />           <ContactCard />           <ContactCard />           <ContactCard />           <div className="contact-card">               <img align="center" src="http://placekitten.com/300/200"/>               <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>               <p>Phone: (212) 555-1234</p>               <p>Email: mr.whiskaz@catnap.meow</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/200"/>               <h3><font color="#3AC1EF">▍Fluffykins</font></h3>               <p>Phone: (212) 555-2345</p>               <p>Email: fluff@me.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/400/300"/>               <h3><font color="#3AC1EF">▍Destroyer</font></h3>               <p>Phone: (212) 555-3456</p>               <p>Email: ofworlds@yahoo.com</p>           </div>                     <div className="contact-card">               <img align="center" src="http://placekitten.com/200/100"/>               <h3><font color="#3AC1EF">▍Felix</font></h3>               <p>Phone: (212) 555-4567</p>               <p>Email: thecat@hotmail.com</p>           </div>       </div>   ) } export default App 

الآن ، دعونا نعمل على الكود المستخدم في إنشاء مكون ContactCard . من خلال إنشاء عناصر HTML منتظمة ، يمكننا تخصيص سماتها التي تؤثر على سلوكها ومظهرها. يتم ترميز أسماء هذه السمات حسب المعيار. في حالة المكونات ، يمكنك استخدام الطريقة نفسها تمامًا ، مع وجود الفرق الوحيد في أننا نتوصل إلى أسماء السمات أنفسنا ، ونقرر بأنفسنا كيفية استخدامها في رمز المكون.

تحتوي كل بطاقة على أربعة أجزاء من المعلومات ، والتي ، من بطاقة إلى أخرى ، يمكن أن تتغير. هذه صورة لقطة واسمها ، بالإضافة إلى هاتف وعنوان بريد إلكتروني. دع اسم القط موجودًا في خاصية name وعنوان الصورة في خاصية imgURL والهاتف في خاصية phone وعنوان البريد الإلكتروني في خاصية email .

لقد قمنا بتعيين هذه الخصائص على مثيلات مكونات ContactCard ، وبما أننا نقوم بنقل البيانات من الكود الموجود بالفعل في App ، سنقوم بحذف الأجزاء المقابلة لها. نتيجة لذلك ، سيبدو رمز مكون App كما يلي:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               name="Mr. Whiskerson"               imgUrl="http://placekitten.com/300/200"               phone="(212) 555-1234"               email="mr.whiskaz@catnap.meow"           />                     <ContactCard               name="Fluffykins"               imgUrl="http://placekitten.com/400/200"               phone="(212) 555-2345"               email="fluff@me.com"           />                     <ContactCard               name="Destroyer"               imgUrl="http://placekitten.com/400/300"               phone="(212) 555-3456"               email="ofworlds@yahoo.com"           />                     <ContactCard               name="Felix"               imgUrl="http://placekitten.com/200/100"               phone="(212) 555-4567"               email="thecat@hotmail.com"           />                 </div>   ) } export default App 

صحيح أن مجرد نقل الخصائص إلى مكون لا يكفي لاستخدامها فيه. ستحتوي الصفحة ، التي سيتم تشكيلها بواسطة مكون App أعلاه ، على أربع بطاقات متطابقة ، يتم تعيين بياناتها في رمز مكون ContactCard ، الذي لا يعرف حتى الآن ما يجب القيام به بالخصائص المنقولة إليه.


بيانات البطاقة مضغوطة في الرمز ؛ لا يمكن للمكون العمل مع الخصائص التي تم تمريرها إليها

لذا حان الوقت للتحدث عن كيفية عمل مكون ContactCard مع الخصائص التي يتم تمريرها إليه عند إنشاء مثيل له.

ننتقل إلى حل هذه المشكلة من خلال الإشارة ، عند الإعلان عن وظيفة ContactCard ، إلى أنها تقبل معلمة props . في هذه الحالة ، سيبدو رمز المكون كما يلي:

 import React from "react" function ContactCard(props) {   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

في الواقع ، يمكن تسمية هذه المعلمة بأي شيء تريده ، ولكن في React ، من المعتاد أن نسميها props ، وغالبًا ما تسمى الخصائص التي نتحدث عنها هنا ببساطة "props".

المعلمة props هو كائن. خصائص هذا الكائن هي الخصائص التي يتم تمريرها إلى المكون عندما يتم إنشاء مثيل له. هذا ، على سبيل المثال ، في كائن props بنا سيكون props اسم خاصية props.name يحتوي على اسم القط الذي تم تمريره إلى المكون عندما تم إنشاء مثيل له. بالإضافة إلى ذلك ، سيكون لها خصائص props.imgUrl ، props.phone ، props.email . للتحقق من ذلك ، أضف الأمر console.log(props) في بداية وظيفة ContactCard .

 import React from "react" function ContactCard(props) {   console.log(props)   return (       <div className="contact-card">           <img align="center" src="http://placekitten.com/300/200"/>           <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3>           <p>Phone: (212) 555-1234</p>           <p>Email: mr.whiskaz@catnap.meow</p>       </div>   ) } export default ContactCard 

سيؤدي هذا إلى إحضار كائن props تلقاه المكون إلى وحدة التحكم.


وجوه الدعائم وحدة

هنا يمكنك رؤية إخراج أربعة كائنات من ContactCard.js . يوجد الكثير منهم لأننا نقوم بإنشاء أربعة مثيلات لمكون ContactCard .

كل هذا يعطينا فرصة لاستخدام في رمز المكون ، بدلاً من القيم المرمزة ، ما تم تمريره إليه عند إنشاء مثيله ، المتاح في شكل props كائن props .

ماذا لو حاولنا استخدام خاصية props.imgUrl هذا:

 <img align="center" src=props.imgUrl/> 

للوهلة الأولى ، قد تعمل مثل هذه الإنشاءات ، ولكن تذكر أننا نحتاج هنا إلى استخدام كيان من JavaScript في كود JSX. تحدثنا عن كيفية القيام بذلك في واحدة من الفصول السابقة. وهي ، في حالتنا ، يجب إرفاق خاصية الكائن بأقواس:

 <img align="center" src={props.imgUrl}/> 

نقوم بمعالجة العناصر الأخرى التي يتم إرجاعها بواسطة المكون بنفس الطريقة ، وبعد ذلك يأخذ الكود الخاص به بالشكل التالي:

 import React from "react" function ContactCard(props) {   return (       <div className="contact-card">           <img align="center" src={props.imgUrl}/>           <h3><font color="#3AC1EF">▍{props.name}</font></h3>           <p>Phone: {props.phone}</p>           <p>Email: {props.email}</p>       </div>   ) } export default ContactCard 

يرجى ملاحظة أنه في الحقول الخاصة بعرض الهاتف وعنوان البريد الإلكتروني ، تركنا النصوص Phone: Email: مع وجود مسافات تتبعها ، حيث يتم استخدام هذه النصوص في جميع المكونات. إذا نظرت الآن إلى صفحة التطبيق ، ستلاحظ أنها تحتوي على أربع بطاقات مختلفة.


تشكلت الصفحة باستخدام مكون عالمي

يقبل مكوننا أربعة خصائص فقط. ماذا لو كان المكون يحتاج إلى تمرير ، على سبيل المثال ، 50 خاصية؟ ربما يكون تمرير كل خاصية مثل سطر منفصل ، كما هو الحال في مكون App ، غير مريح. في مثل هذه الحالات ، يمكنك استخدام طريقة أخرى لنقل الخصائص إلى المكونات. يتكون ذلك في حقيقة أنه عند تكوين نسخة من المكون ، لا يتم نقله بقائمة الخصائص ، ولكن في عنصر ذو خصائص. إليك كيف يمكن أن تبدو على مثال المكون الأول:

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               contact={{                 name: "Mr. Whiskerson",                 imgUrl: "http://placekitten.com/300/200",                 phone: "(212) 555-1234",                 email: "mr.whiskaz@catnap.meow"               }}           />                     <ContactCard               name="Fluffykins"               imgUrl="http://placekitten.com/400/200"               phone="(212) 555-2345"               email="fluff@me.com"           />                     <ContactCard               name="Destroyer"               imgUrl="http://placekitten.com/400/300"               phone="(212) 555-3456"               email="ofworlds@yahoo.com"           />                     <ContactCard               name="Felix"               imgUrl="http://placekitten.com/200/100"               phone="(212) 555-4567"               email="thecat@hotmail.com"           />                 </div>   ) } export default App 

هذا لا يعني أن هذا الأسلوب قلل إلى حد كبير مقدار الشفرة المستخدمة لوصف مثيل المكون. الحقيقة هي أن الخصائص التي تم تمريرها إلى المكون لا تزال مشفرة في التعليمات البرمجية ، على الرغم من أننا نقوم بتمرير مكون واحد فقط إلى المكون. يمكن الشعور بمزايا هذا النهج في المواقف التي يتم فيها الحصول على بيانات المكون من بعض المصادر الخارجية. على سبيل المثال ، من ملف JSON.

أثناء تعديل رمز مكون App المستخدم لإنشاء المثيل الأول لمكون ContactCard ، تعطلت العملية الصحيحة للتطبيق. هكذا تبدو صفحته الآن.


عطل التطبيق

كيف يمكن إصلاح هذا؟ لفهم ذلك ، سيكون من المفيد تحليل ما يحدث باستخدام الأمر console.log(props) .


تحليل الكائن الدعائم

كما ترون ، يختلف كائن props الخاص بالمكون الأول عن الكائن نفسه للمكونين الثاني والتالي.

في مكون ContactCard نستخدم كائن props بناءً على افتراض أنه يحتوي على name ، imgUrl وغيرها من الخصائص. هنا ، يتلقى المكون الأول خاصية واحدة فقط - contact . هذا يؤدي إلى حقيقة أن كائن props لديه خاصية واحدة فقط - contact ، وهو الكائن ، ورمز المكون لا يوفر العمل مع مثل هذه البنية.

تحويل المكون الخاص بنا إلى نموذج استخدام خاصية واحدة فقط لكائن contact يحتوي على خصائص أخرى أمر بسيط للغاية. للقيام بذلك ، على سبيل المثال ، للوصول إلى خاصية name ، يكفي استخدام بنية النموذج props.contact.name في رمز المكون. تصاميم مماثلة تسمح لنا بالعمل بشكل صحيح مع الخصائص الأخرى التي نحتاجها.

دعنا نعيد تدوير رمز المكون ، مع الأخذ في الاعتبار نقل contact كائن-كائن واحدة تحتوي على خصائص أخرى:

 import React from "react" function ContactCard(props) {   console.log(props)   return (       <div className="contact-card">           <img align="center" src={props.contact.imgUrl}/>           <h3><font color="#3AC1EF">▍{props.contact.name}</font></h3>           <p>Phone: {props.contact.phone}</p>           <p>Email: {props.contact.email}</p>       </div>   ) } export default ContactCard 

يجب الآن عرض المكون الأول بشكل طبيعي ، لكننا لن نرى هذا في هذه المرحلة من المشروع ، حيث سيقوم النظام بإبلاغنا بالكثير من الأخطاء المتعلقة بحقيقة أن العديد من مثيلات مكون ContactCard تم إنشاؤها في مكون App لا تتلقى خاصية - كائن contact . عند تنفيذ الكود ، ستكون هذه الخاصية undefined . نتيجة لذلك ، جرت محاولة للإشارة إلى خاصية معينة ذات قيمة undefined ، مما يؤدي إلى حدوث خطأ. سنقوم بإصلاح هذا من خلال معالجة رمز مكون App المسؤول عن تكوين مكونات ContactCard :

 import React from "react" import ContactCard from "./ContactCard" function App() {   return (       <div className="contacts">           <ContactCard               contact={{                 name: "Mr. Whiskerson",                 imgUrl: "http://placekitten.com/300/200",                 phone: "(212) 555-1234",                 email: "mr.whiskaz@catnap.meow"               }}           />                     <ContactCard               contact={{                 name: "Fluffykins",                 imgUrl: "http://placekitten.com/400/200",                 phone: "(212) 555-2345",                 email: "fluff@me.com"               }}           />                     <ContactCard               contact={{                 name: "Destroyer",                 imgUrl: "http://placekitten.com/400/300",                 phone: "(212) 555-3456",                 email: "ofworlds@yahoo.com"               }}           />                     <ContactCard               contact={{                 name: "Felix",                 imgUrl: "http://placekitten.com/200/100",                 phone: "(212) 555-4567",                 email: "thecat@hotmail.com"               }}           />                 </div>   ) } export default App 

الآن ستظهر صفحة التطبيق كما كانت من قبل.

كالمعتاد ، يوصى بتجربة المفاهيم التي تعلمتها اليوم من أجل فهمها بشكل أفضل. على سبيل المثال ، يمكنك العمل مع الكود وإضافة خصائص جديدة يتم تمريرها إلى المكون ومحاولة استخدامها في المكون.

ملخص


اليوم قدمنا ​​مفهوم الخصائص التي يمكن نقلها إلى مكونات React من أجل التحكم في سلوكها ومظهرها. تشبه هذه الخصائص سمات عناصر HTML ، ولكن باستخدام الخصائص في المكونات ، يقرر المبرمج بشكل مستقل ما معنى هذه العناصر وماذا تفعل بالضبط بها في المكون. في المرة القادمة سيكون لديك درس عملي في العمل مع خصائص المكون والتصميم.

أعزائي القراء! كيف جربت الكود الخاص بمثال اليوم من أجل فهم خصائص مكونات React بشكل أفضل؟

Source: https://habr.com/ru/post/ar436032/


All Articles