في جزء اليوم من ترجمة البرنامج التعليمي React ، سننتهي من العمل على تطبيق Todo ونتحدث عن كيفية استخدام البيانات من المكونات الداخلية وقدرات JavaScript القياسية لتحميل البيانات من مصادر خارجية.

→
الجزء 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: مشروع المقررالدرس 39. ورشة العمل. تطبيق TODO. المرحلة رقم 7
→
الأصلob الوظيفة
الآن تطبيق Todo يشبه الشكل التالي.
صفحة التطبيق في المتصفحيبدو
TodoItem
مكون
TodoItem
كما يلي:
import React from "react" function TodoItem(props) { return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} /> <p>{props.item.text}</p> </div> ) } export default TodoItem
مهمتك هي نمط عناصر القائمة وفقا لحالتها. يجب أن يكون مظهر الحالات المكتملة مختلفًا عن غير المكتمل. عند تنسيق عناصر القائمة التي تمثل المهام المكتملة ، يمكن تدوين نصها باللون الرمادي أو يمكن شطبها أو تغيير خطها أو إجراء تعديلات أخرى.
olution الحل
يمكن حل المشكلة المقدمة هنا بطرق مختلفة. سوف نستخدم النمط المضمن ، والذي
TodoItem
بأنه ثابت نمط ثابت في رمز المكون الوظيفي
TodoItem
. نحن هنا تكوين خصائص النص
fontStyle
color
textDecoration
. بعد ذلك ، باستخدام تقنية التقديم الشرطي ، سنخصص هذا النمط لعنصر
<p>
إذا تم تمييز الحالة المستخلصة منه على أنها مكتملة.
props.item.completed
ذلك بناءً على الخاصية التي تم تمريرها إلى مثيل المكون ، والذي يتوفر به كـ
props.item.completed
.
سيبدو رمز المكون المحول كما يلي:
import React from "react" function TodoItem(props) { const completedStyle = { fontStyle: "italic", color: "#cdcdcd", textDecoration: "line-through" } return ( <div className="todo-item"> <input type="checkbox" checked={props.item.completed} onChange={() => props.handleChange(props.item.id)} /> <p style={props.item.completed ? completedStyle: null}>{props.item.text}</p> </div> ) } export default TodoItem
إليك كيفية تغيير شكل صفحة التطبيق.
تم تغيير صفحة التطبيق في المتصفحفي الوقت نفسه ، يتم تطبيق الأنماط عند إعداد وإلغاء تحديد العلامات التي تشير إلى حالة العناصر في قائمة المهام.
هذا يختتم العمل على تطبيق تودو.
الدرس 40. تنزيل البيانات من المصادر الخارجية
→
الأصلفي درس حول أساليب دورة حياة المكون ، تحدثنا عن أسلوب
componentDidMount()
. حاول أن تتذكر كيف تعمل. تسمح لك هذه الطريقة بالتدخل في تشغيل المكون عن طريق تنفيذ بعض التعليمات البرمجية مباشرة بعد إضافة المكون إلى شجرة DOM. عندما تحدثنا عن أساليب دورة حياة المكون ، ذكرت أن أسلوب
componentDidMount()
غالبًا ما يستخدم لتحميل البيانات من بعض المصادر الخارجية. يتم استخدام هذه البيانات من قبل المكون لتحقيق الغرض منه.
دعنا نبدأ تجاربنا اليوم مع مشروع جديد تم إنشاؤه باستخدام أدوات إنشاء تطبيق التفاعل
App.js
الذي يحتوي ملف
App.js
على الكود التالي:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } render() { return ( <div> Code goes here </div> ) } } export default App
في رمز مكون
App
المستند إلى المكون ، نصف طريقة
componentDidMount()
ونتحقق من قابلية التشغيل للتكوين الناتج عن طريق إخراج شيء ما إلى وحدة التحكم من هذه الطريقة.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = {} } componentDidMount() { console.log("Hi!") } render() { return ( <div> Code goes here </div> ) } } export default App
الإخراج إلى سلسلة وحدة التحكم
Hi!
يثبت وظيفة الكود ، حتى نتمكن من مواصلة العمل. كما ذكرنا سابقًا ، تقوم هذه الطريقة عادةً بتحميل البيانات اللازمة للمكون للعمل.
في هذا الدرس ، سوف نستخدم العديد من الأدوات المساعدة التي ستكون مفيدة لنا عند تحميل البيانات في المكون.
أول واحد هو ميزة جافا سكريبت المضمنة. نحن نتحدث عن
API Fetch ، وهي واجهة ملائمة للحصول على الموارد ، بناءً على
الوعود ، والتي تتيح لك تنفيذ طلبات HTTP ، والتي يتم من خلالها تحميل البيانات.
الأداة الثانية التي سنستخدمها هي
واجهة برمجة تطبيقات حرب النجوم . هذا المشروع جيد لأنه يمكن استخدامه في التطبيقات الأمامية دون أي صعوبات خاصة (على وجه الخصوص ، نحن نتحدث عن ميزات تكوين CORS).
في طريقة
componentDidMount()
، سنستخدم الدالة
fetch()
، لتمريرها عنوان تحميل البيانات ، وتحويل هذه البيانات إلى النوع الذي نحتاج إليه ، ومن أجل التحقق من التشغيل الصحيح للنظام ، قم بإخراج هذه البيانات إلى وحدة التحكم. نقوم بتحويل رمز الطريقة إلى النموذج التالي:
componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => console.log(data)) }
هنا نقوم بتنزيل بيانات حول بطل معين للفيلم ، في إشارة إلى واجهة برمجة التطبيقات ، وبعد ذلك نقوم بتحويل ما جاء من الخادم إلى تنسيق JSON ، ثم نطبع هذه البيانات إلى وحدة التحكم. ما حصل في وحدة التحكم هو مبين في الشكل التالي.
يتم إخراج البيانات التي تم تنزيلها من Star Wars API إلى وحدة التحكمكما ترون ، وصل كائن يحتوي على بيانات حول Luke Skywalker إلى وحدة التحكم. الآن ، بعد أن لدينا البيانات ، نحتاج إلى التفكير في كيفية عرضها على صفحة التطبيق. لحل هذه المشكلة ، يجب أولاً مراعاة حقيقة أن البيانات التي يتم تنزيلها من الخارج ، إذا لم يتم حفظها في أي مكان ، لن يكون من الممكن عرضها على صفحة التطبيق في المستعرض. المكان الذي يعمل على تخزين هذه البيانات هو حالة المكون. أضف خاصية جديدة ،
character
، ممثلاً بكائن فارغ في حالة المكون:
this.state = { character: {} }
سنقوم بتخزين كائن في هذه الخاصية مع وصف للشخصية ، يتم تنزيل بيانات حوله من مصدر خارجي. إنها موجودة ككائن ، لذلك عندما نهيئ الحالات ، نجعل خاصية
character
كائنًا فارغًا.
بعد ذلك ، في هذا المكان من كود طريقة
componentDidMount()
، حيث نحصل على البيانات ،
setState()
إلى الحالة باستخدام طريقة
setState()
. علاوة على ذلك ، في هذه الحالة ، فإن ما تم تخزينه في الولاية قبل ذلك لا يهمنا ، وبالتالي ، يمكننا ببساطة تمرير كائن يحتوي على تمثيل جديد للدولة بهذه الطريقة. نتيجة لذلك ، وصلنا إلى رمز الأسلوب
componentDidMount()
:
componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) }
للتحقق من التشغيل الصحيح للآليات الموجودة الآن في الكود ، سنقوم في طريقة
render()
شيء يجب أن يكون موجودًا في الحالة بعد كتابة البيانات المحملة عليها. الآن
App.js
رمز ملف
App.js
كما يلي:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { character: {} } } componentDidMount() { fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) } render() { return ( <div> {this.state.character.name} </div> ) } } export default App
وهنا كيف ستبدو صفحة التطبيق في المتصفح.
صفحة التطبيق في المتصفحيوضح عرض نص
Luke Skywalker
على الصفحة كيفية عمل آليات تحميل البيانات.
يستخدم تطبيقنا طلبًا بسيطًا ، استجابةً لتلقي التطبيق كمية صغيرة من البيانات التي يتم معالجتها وعرضها بسرعة على الصفحة. يستغرق القليل من الوقت لإكمال كل هذه الإجراءات. لذلك ، يتم عرض البيانات على الشاشة بسرعة بحيث نحصل على الانطباع بأن المكون ، مباشرة بعد عرضها على الشاشة ، يحتوي بالفعل. ولكن إذا تم الوصول إلى مصدر البيانات البعيد باستخدام خط اتصال بطيء جدًا ، أو استجابة لواجهة برمجة التطبيقات التي تم تحميل البيانات منها ببطء ، فقد يستغرق الأمر وقتًا طويلاً قبل أن يتمكن التطبيق من عرض هذه البيانات على الشاشة . كل هذا الوقت ، ستبقى الشاشة فارغة. إذا حدث هذا في التطبيقات الواقعية ، فإنه يربك المستخدمين لديهم ، والذين قد يقررون أن هذه التطبيقات لا تعمل بشكل صحيح. من أجل توقع موقف مشابه ، من الضروري ، أثناء تحميل ومعالجة البيانات ، أن تُظهر للمستخدم رسالة مقابلة. لا ينطبق هذا على موضوعنا اليوم ، ولكن من المناسب هنا مناقشته.
في التطبيقات الحقيقية ، لتنبيه المستخدم بأنه بحاجة إلى انتظار إجراء معين ، مثل تنزيل البيانات ، يستخدمون مؤشرًا يشبه التحميل. في حالتنا ، إلى أن يتم تحميل البيانات وجاهزة للعرض على الصفحة ، سنقوم فقط بعرض
loading...
النص
loading...
من خلال القيام بذلك ، سنكون قادرين على تقييم الاحتمالات التي يوفرها لنا تخزين البيانات في حالة التطبيق.
أضف خاصية جديدة إلى الحالة ، مع الإشارة إلى ما إذا كان يتم تحميل البيانات في وقت ما. نسميها
loading
وتهيئته
false
. بعد ذلك ، مباشرة قبل تحميل البيانات باستخدام
fetch()
، نكتب إلى هذه الخاصية.
بعد ذلك ، في طريقة
render()
، استنادًا إلى خاصية حالة
loading
، سنقوم بتكوين النص المعروض على الصفحة. إليك
App.js
الذي
App.js
شفرة
App.js
بعد هذه التحويلات.
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { loading: false, character: {} } } componentDidMount() { this.setState({loading: true}) fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ character: data }) }) } render() { const text = this.state.loading ? "loading..." : this.state.character.name return ( <div> <p>{text}</p> </div> ) } } export default App
هذا الرمز ، ومع ذلك ، لا يعمل بشكل صحيح. وهذا هو ما تبدو عليه صفحة التطبيق الآن.
صفحة التطبيق في المتصفحمن المفترض أن يتم عرض نقش
loading...
فقط عند تنزيل البيانات من مصدر خارجي ، ولكن يبدو أنه يتم عرضه الآن على الصفحة باستمرار. قبل قراءة المزيد ، حاول البحث عن الأخطاء وتصحيحها في الكود.
في الواقع ، المشكلة هنا هي أنه قبل بدء تحميل البيانات ، قمنا بتعيين
loading
على "
true
، وبعد اكتمال التنزيل ، لم
loading
false
في
loading
. نتيجة لذلك ، يتم دائمًا عرض النص الذي يتم
loading...
على الصفحة. ليس من الصعب إصلاح هذا الخطأ. يكفي ، في نفس المكان الذي نكتب فيه البيانات المحملة إلى الحالة ، عيّن
loading
إلى
false
. نتيجة لذلك ،
App.js
يأخذ رمز
App.js
النموذج التالي:
import React, {Component} from "react" class App extends Component { constructor() { super() this.state = { loading: false, character: {} } } componentDidMount() { this.setState({loading: true}) fetch("https://swapi.co/api/people/1") .then(response => response.json()) .then(data => { this.setState({ loading: false, character: data }) }) } render() { const text = this.state.loading ? "loading..." : this.state.character.name return ( <div> <p>{text}</p> </div> ) } } export default App
الآن ، عند تحميل البيانات ، يظهر نقش
loading...
لفترة وجيزة ، وبعد ذلك يتم عرض اسم الحرف على الصفحة.
النتائج
في هذا الدرس ، أكملت العمل على تطبيق Todo وتعلمت كيفية استخدام طريقة دورة حياة
componentDidMount()
و API Fetch القياسية لتحميل البيانات من مصادر خارجية ومعالجتها وعرضها على الصفحات. بالإضافة إلى ذلك ، تحدثنا هنا عن تنفيذ آلية لإعلام المستخدم بعمليات تنفيذ التطبيق ، والتي قد تستغرق الكثير من الوقت. في المرة القادمة سوف نتحدث عن النماذج.
أعزائي القراء! كيف يمكنك تحميل البيانات من مصادر خارجية في تطبيقات React؟