في جزء اليوم من ترجمة دورة التدريب 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: مشروع المقررالدرس 43. ورشة العمل. العمل مع النماذج
→
الأصل▍Zadanie
في هذا الدرس العملي ، تتم دعوتك لإحضار رمز مكون
App
، الموجود في ملف
App.js
الخاص بالمشروع القياسي الذي تم إنشاؤه بواسطة create-react-app. هنا هو الكود:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <main> <form> <input placeholder="First Name" /><br /> <input placeholder="Last Name" /><br /> <input placeholder="Age" /><br /> {/* */} <br /> {/* */} <br /> {/* */} <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {/* */}</p> <p>Your age: {/* */}</p> <p>Your gender: {/* */}</p> <p>Your destination: {/* */}</p> <p> Your dietary restrictions: {/* */} </p> </main> ) } } export default App
بشكل عام ، مهمتك هي التأكد من أن البيانات التي يدخلها المستخدم أثناء العمل مع عناصر تحكم النموذج تظهر فورًا في النص الموجود أسفل هذا النموذج. استفد من تكنولوجيا
المكونات المدارة عند إتمام المهمة. تجدر الإشارة إلى أن المهمة المقدمة لك هي نسخة معدلة من
هذه المهمة ، حتى تتمكن من إلقاء نظرة عليها من أجل فهم أفضل لميزات عناصر التحكم التي تمت دعوتك لإنشاءها وتكوينها.
إليك ما يعرضه المكون الآن على الشاشة.
تطبيق في المتصفح▍Reshenie
يمكنك التعامل مع حل المشكلة المقترحة لك من زوايا مختلفة. سنبدأ بوضع كل ما نحتاجه في الحالة ، وبعد ذلك سنضع الضوابط والآليات الأخرى للمكون.
في الوقت الحالي ، ستبدو حالة المكون كما هو موضح أدناه.
this.state = { firstName: "", lastName: "", age: 0, gender: "", destination: "", dietaryRestrictions: [] }
من الضروري مراعاة حقيقة أنه في عملية العمل على برنامج قد يتضح أنه ، على سبيل المثال ، سيكون أكثر ملاءمة لتهيئة الحالة بشكل مختلف. إذا واجهنا شيئًا مماثلاً ، فسنغير رمز تهيئة الحالة. على وجه الخصوص ، قد يكون سبب بعض الشكوك الآن هو الرقم 0 المكتوب في خاصية
age
، والتي من المفترض أن تخزن فيها العمر الذي أدخله المستخدم. ربما ، سيكون من الضروري القيام بخلاف ذلك مع نظام تخزين بيانات العلم ، والذي يتم تمثيله الآن
dietaryRestrictions
، التي تمت تهيئتها بواسطة صفيف فارغ.
الآن ، بعد تهيئة الحالة ، دعنا نعتني بإعداد الضوابط. نظرًا لأن الكود يحتوي بالفعل على وصف لحقول الإدخال - فلنبدأ بها.
ستحتاج عناصر التحكم هذه إلى إعطاء أسماء من خلال تعيين سمات
name
الخاصة بها بحيث تتطابق مع أسماء خصائص الحالة التي سيتم تخزين البيانات المدخلة فيها. يجب أن يكون لديهم سمة قيمة يتم تحديد قيمتها بناءً على البيانات المخزنة في الولاية. عند إدخال البيانات في كل حقل من هذه الحقول ، تحتاج إلى تمرير البيانات التي تم إدخالها إلى المكون ، مما يؤدي إلى الحاجة إلى امتلاك
onChange
أحداث
onChange
. كل هذه الاعتبارات تؤدي إلى حقيقة أن وصف الحقول الآن يبدو كما يلي:
<input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" />
كطريقة تستخدم لمعالجة أحداث
onChange
في هذه الحقول ، لا يزال
this.handleChange
غير موجود. قم بإنشاء هذه الطريقة:
handleChange(event) { const {name, value} = event.target this.setState({ [name]: value }) }
نحن هنا نستخرج خصائص
name
value
من كائن
event.target
، ثم نستخدمها لتعيين خاصية الحالة المقابلة. في الوقت الحالي ، سوف تلائمنا شفرة معالج الأحداث العالمية هذه ، لكن في وقت لاحق ، عندما نبدأ العمل مع الأعلام ، سنقوم بإجراء تغييرات عليها.
لا تنسى
this
الرابط المنجز في مُنشئ المكون:
this.handleChange = this.handleChange.bind(this)
من أجل تحقيق الإخراج في أسفل صفحة البيانات المدخلة في
firstName
secondName
age
، سنعمل مع عناصر
<p>
المقابلة ،
secondName
إلى النموذج التالي:
<p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p>
الآن دعونا نلقي نظرة على ما حصلنا عليه.
تطبيق في المتصفحكما ترون ، في الحقل الخاص بإدخال العمر ، لا يتم عرض تلميح. بدلاً من ذلك ، يتم عرض ما تم تعيينه في خاصية الحالة
age
، أي 0. نحتاج إلى تلميح في الحقل الفارغ. دعنا نحاول استبدال قيمة
age
في الولاية بالقيمة
null
. بعد ذلك ، اتضح أن النموذج يبدو كما يجب ، ولكن يتم عرض التحذير التالي في وحدة التحكم فيما يتعلق بحقل
age
:
Warning: `value` prop on `input` should not be null. Consider using an empty string to clear the component or `undefined` for uncontrolled components
نتيجةً لذلك ، سنحتاج إلى استبدال قيمة خاصية الحالة
age
بسلسلة فارغة ، وبذلك يتم إدخال رمز تهيئة الحالة إلى النموذج التالي:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: [] }
جرب الآن النموذج. بعد الافتتاح مباشرة ، سيبدو كما هو في بداية العمل ، أي أن الموجه سيعود إلى الحقل
age
. عند ملء الحقول ، سيتم عرض البيانات المدخلة في أسفل الصفحة.
تطبيق في المتصفحكما ترون ، في هذه المرحلة من العمل ، كل شيء يعمل كما هو متوقع.
الآن سوف نشارك في عناصر جديدة. ستكون الخطوة التالية في العمل على النموذج إضافة مفاتيح إليه.
نلف المفاتيح في
<label>
، والتي لن تسمح لنا فقط بتوقيع رمز التبديل ، ولكن أيضًا للتأكد من أن النقر فوق هذا التوقيع ، أي العنصر الأصلي ، يؤدي إلى تحديده.
عند العمل مع رموز التبديل ، يجدر أن نتذكر أنها نوع من مجموعة من العلامات مع السمة
checked
وحقول النص التي لها سمة
value
. تشكل مفاتيح التبديل مجموعة يتم فيها تعيين كل مفتاح من رموز التبديل بنفس الاسم ، ويتم تعيين الخاصية
checked
لمفاتيح التبديل وفقًا لحالة تم تكوينها بحيث يكون من المستحيل تشغيل أكثر من مفتاح واحد يمثل جزءًا من نفس المجموعة.
onChange
الأحداث لمفاتيح التبديل
onChange
.
نتيجة لذلك ، سيبدو رمز وصف المحول كما يلي:
<label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label>
سنقوم الآن بمعالجة عنصر
<p>
المقابل الموجود في أسفل الصفحة ، على النحو التالي:
<p>Your gender: {this.state.gender}</p>
بعد ذلك ، يمكن اختبار النموذج. بعد بدء التشغيل مباشرة ، لا يتم تحديد كلا المحولين ، حيث يتم تخزين الحالة بقيمة لا تسمح بأي من عمليات الفحص التي تم إجراؤها عند تعيين الخاصية التي
checked
منها
checked
true
. بعد النقر فوق أحدهما ، تندرج القيمة المطابقة في الحالة (المخزنة في سمة
value
المفتاح) ، ويتم تحديد رمز التبديل ، ويتم عرض النص المقابل في أسفل النموذج.
تطبيق في المتصفحالآن دعونا نعمل على مربع التحرير والسرد. الشغل له يشبه هذا:
<select> <option></option> <option></option> <option></option> <option></option> </select>
يوضح هذا الرمز أننا نخطط لوصف مربع تحرير وسرد يحتوي على أربعة عناصر.
تحتوي العلامة
<select>
وعلاماتها
<option>
على سمة
value
. ومع ذلك ، فإن هذه الصفات تحمل معاني مختلفة. تشير قيمة
value
المعينة لعنصر
<option>
إلى ما يجب أن تكون عليه خاصية الحالة المقابلة عند تحديد هذا العنصر. هذه هي الخطوط التي يجب أن تكون في القائمة المنسدلة. في حالتنا ، هذه هي بعض الوجهات ، على سبيل المثال ، البلدان. دعنا نكتب أسمائهم بحرف صغير حتى يتوافق مظهرهم مع قيم خصائص
value
العناصر الأخرى في الكود. بعد ذلك ، سيبدو رمز مربع التحرير والسرد كما يلي:
<select value=> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
إذا تحدثنا عن سمة
value
<select>
، فلن تتم الإشارة هنا إلى بعض القيمة المرمّزة ، ولكن رابطًا إلى خاصية الحالة المقابلة:
<select value={this.state.destination}> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
تعيين الحقل سمات أخرى. على وجه الخصوص ، الاسم المطابق لاسم الخاصية في الولاية ،
onChange
أحداث
onChange
،
this.handleChange
.
<select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
سنقوم الآن بتهيئة وصف العنصر
<p>
، والذي سيعرض ما تم تحديده في حقل
destination
:
<p>Your destination: {this.state.destination}</p>
إذا نظرت إلى الصفحة في المتصفح الآن ، يمكنك أن ترى أن العنصر الأول من القائمة يتم تحديده تلقائيًا في الحقل ، لكن هذا ، بالطبع ، لا يؤدي إلى تحديث الحالة ، حيث لا يتم عرض أي شيء بعد النقطتين في السطر
Your destination:
سطر.
تطبيق في المتصفحلكي تندرج قيمة
germany
في الحالة ، تحتاج إلى فتح مربع التحرير والسرد وتحديد شيء آخر أولاً ، ثم تحديد
Germany
.
في كثير من الأحيان ، من أجل مراعاة هذه الميزة في حقول القائمة ، في قوائمها ، باعتبارها العنصر الأول ، فإنها تضع شيئًا ما كعنصر ذي قيمة فارغة وبنص مثل
-- Please Choose a destination --
. في حالتنا ، قد يبدو مثل هذا:
<select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select>
سوف نركز على هذا الخيار لتحديد مربع التحرير والسرد.
الآن دعنا نتعامل مع ، ربما ، الجزء الأكثر صعوبة من مهمتنا ، المرتبطة بالأعلام. هنا تجدر الإشارة إلى أن خاصية ممتلكات الدولة
dietaryRestrictions
، والتي تم التخطيط لاستخدامها للعمل مع الأعلام ، تمت تهيئتها باستخدام صفيف فارغ. الآن ، عندما يتعلق الأمر بالعمل مع عناصر التحكم ، هناك شعور بأنه سيكون من الأفضل تمثيل هذا الحقل ككائن. لذلك سيكون أكثر ملاءمة للعمل مع الكيانات التي تمثل العلامات الفردية في شكل خصائص هذا الكائن مع أسماء مألوفة ، وليس في شكل عناصر مجموعة. ستحتوي خصائص الكائن ، والتي سيتم تمثيلها الآن بواسطة
dietaryRestrictions
حالة
dietaryRestrictions
النظام
dietaryRestrictions
، على قيم منطقية تشير إلى ما إذا تم إلغاء تحديد خانة الاختيار المقابلة (
false
) أو تحديدها (
true
). الآن سيبدو رمز تهيئة الحالة كما يلي:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", dietaryRestrictions: { isVegan: false, isKosher: false, isLactoseFree: false } }
كما ترون ، نخطط لإنشاء ثلاثة أعلام. سيتم إعادة تعيين كل منهم ، فور تحميل الصفحة.
وصفنا العلامات الموجودة في الكود الذي تم إرجاعه بواسطة المكون ، ولفها بالعلامات
<label>
وتحديد سماتها. إليك ما سيبدو عليه الكود:
<label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.dietaryRestrictions.isLactoseFree} /> Lactose Free? </label>
أسماء العلامات المستخدمة هي أسماء الخصائص الخاصة
dietaryRestrictions
"
dietaryRestrictions
، وقيم السمات التي تم
checked
منها هي إنشاءات للنموذج
this.state.dietaryRestrictions.isSomething
.
يرجى ملاحظة أنه على الرغم من
onChange
الموجود بالفعل على
onChange
أحداث
this.handleChange
، يجب علينا إجراء بعض التغييرات على البرنامج لضمان عمل البرنامج بشكل صحيح.
نلقي نظرة على التطبيق.
تطبيق في المتصفحكما ترون ، يتم عرض العلامات على الصفحة ، لكن المكون لا يحتوي حتى الآن على كل الآليات اللازمة لضمان التشغيل السليم. دعونا نتعامل مع معالج الأحداث.
هنا ، للعمل مع مربعات الاختيار ، نحتاج إلى استخراج
event.target
من الكائن ، بالإضافة إلى الخصائص المستخرجة بالفعل ،
type
والخصائص
checked
. الأول مطلوب للتحقق من نوع العنصر (الإشارات من النوع الذي يمثله سطر
checkbox
) ، والثاني هو معرفة ما إذا كان مربع الاختيار محددًا أم غير محدد. إذا اتضح أنه تم استدعاء المعالج بعد تفاعل المستخدم مع العلم ، فإننا نستخدم إجراء إعداد خاص للحالة. سنتعامل مع أحداث عناصر التحكم الأخرى بالطريقة نفسها كما كان من قبل.
عند تحديث الحالة ، يجب أن يؤخذ في الاعتبار أن React هو نظام ذكي إلى حد ما ، والذي إذا تم تحديث جزء فقط من الحالة ، فسيجمع تلقائيًا في الحالة الجديدة ما لم يتغير مع ما تغير. لكن لا يمكن للمرء أن يكون متأكداً من أن العمل مع خصائص الكائنات ، والتي هي قيم خصائص الدولة ، سيتم بنفس الطريقة. سوف نتحقق من ذلك عن طريق إحضار رمز
handleChange
إلى النموذج التالي. ننتقل هنا من الافتراض بأنه يمكن تغيير خصائص كائن
dietaryRestrictions
واحدة في كل مرة:
handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ dietaryRestrictions: { [name]: checked } }) : this.setState({ [name]: value }) }
إذا قمت بفتح صفحة التطبيق في متصفح ، وبعد تنزيلها مباشرة ، سيبدو كل شيء جيدًا ، عندما تحاول ، على سبيل المثال ، إدخال اسم في حقل
First Name
، سيعمل كل شيء كما كان من قبل ، ولكن عندما تحاول تعيين أحد خانات الاختيار ، سيتم إصدار التحذير التالي :
تحذير: يقوم أحد المكونات بتغيير إدخال خاضع للتحكم في نوع الكتابة بحيث لا يمكن التحكم فيه. لا ينبغي تبديل عناصر الإدخال من التحكم إلى غير المنضبط (أو العكس). حدد بين استخدام عنصر تحكم متحكم فيه أو غير متحكم به طوال عمر المكون. مزيد من المعلومات: fb.me/react-controlled-components
من أجل تحديث محتويات كائن
dietaryRestrictions
بشكل صحيح ، يمكنك استخدام نموذج
setState
الوظيفي لإنشاء نسخة جديدة من الحالة بنفسك. إذا كان يتعين علينا إدارة عدد كبير من الأعلام ، فمن المحتمل أن نكون قد فعلنا ذلك. ولكن هنا سنفعل خلاف ذلك. وهي ، سنجعل خصائص خصائص
dietaryRestrictions
كائن
dietaryRestrictions
، للتخلص من هذا الكائن:
this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false }
سنقوم الآن بتغيير الإعدادات الخاصة بسمات الأعلام ، والتخلص من
dietaryRestrictions
:
<label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label>
وأخيرًا ، قم بتحرير رمز العنصر الذي يعرض معلومات حول القيود الغذائية المحددة من قبل المستخدم:
<p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p>
بعد ذلك ، سوف نتحقق من صحة التطبيق.
تطبيق في المتصفحكما ترون ، كل شيء يعمل كما هو متوقع.
إليك الرمز الكامل لمكون
App
:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { firstName: "", lastName: "", age: "", gender: "", destination: "", isVegan: false, isKosher: false, isLactoseFree: false } this.handleChange = this.handleChange.bind(this) } handleChange(event) { const {name, value, type, checked} = event.target type === "checkbox" ? this.setState({ [name]: checked }) : this.setState({ [name]: value }) } render() { return ( <main> <form> <input name="firstName" value={this.state.firstName} onChange={this.handleChange} placeholder="First Name" /> <br /> <input name="lastName" value={this.state.lastName} onChange={this.handleChange} placeholder="Last Name" /> <br /> <input name="age" value={this.state.age} onChange={this.handleChange} placeholder="Age" /> <br /> <label> <input type="radio" name="gender" value="male" checked={this.state.gender === "male"} onChange={this.handleChange} /> Male </label> <br /> <label> <input type="radio" name="gender" value="female" checked={this.state.gender === "female"} onChange={this.handleChange} /> Female </label> <br /> <select value={this.state.destination} name="destination" onChange={this.handleChange} > <option value="">-- Please Choose a destination --</option> <option value="germany">Germany</option> <option value="norway">Norway</option> <option value="north pole">North Pole</option> <option value="south pole">South Pole</option> </select> <br /> <label> <input type="checkbox" name="isVegan" onChange={this.handleChange} checked={this.state.isVegan} /> Vegan? </label> <br /> <label> <input type="checkbox" name="isKosher" onChange={this.handleChange} checked={this.state.isKosher} /> Kosher? </label> <br /> <label> <input type="checkbox" name="isLactoseFree" onChange={this.handleChange} checked={this.state.isLactoseFree} /> Lactose Free? </label> <br /> <button>Submit</button> </form> <hr /> <h2><font color="#3AC1EF">Entered information:</font></h2> <p>Your name: {this.state.firstName} {this.state.lastName}</p> <p>Your age: {this.state.age}</p> <p>Your gender: {this.state.gender}</p> <p>Your destination: {this.state.destination}</p> <p>Your dietary restrictions:</p> <p>Vegan: {this.state.isVegan ? "Yes" : "No"}</p> <p>Kosher: {this.state.isKosher ? "Yes" : "No"}</p> <p>Lactose Free: {this.state.isLactoseFree ? "Yes" : "No"}</p> </main> ) } } export default App
النتائج
اليوم أكملت العمل العملي على النماذج. ثم كررت ما تعلمته في الفصول السابقة ، ونأمل أن تتعلم شيئًا جديدًا. في المرة القادمة سوف نتحدث عن بنية تطبيقات React.
أعزائي القراء! أخبرني ، هل كان من الصعب إكمال هذا العمل العملي؟
