تعلم React.js عبر بناء المشاريع: تطبيق تذكير أعياد الميلاد خطوة بخطوة
عندما تبدأ في تعلم مهارة جديدة، قد لا تكون الدروس التعليمية المرئية وحدها كافية. يتفق العديد من المطورين على أن أفضل طريقة لإتقان أي تقنية هي عبر التطبيق العملي وبناء المشاريع. لذلك، في هذه السلسلة من المقالات التطبيقية، لن نبني تطبيقًا واحدًا أو اثنين فحسب، بل خمسة تطبيقات React صغيرة ومتوسطة الحجم. ستتطلب منك هذه التطبيقات بناء المشروع بالكامل بنفسك، مما يضمن لك كتابة الكود واجتياز حالات الاختبار وتعلم كل مهارة بشكل فعال.
هل أنت مستعد للانطلاق في رحلة التعلم العملي؟
منهجية العمل في هذه السلسلة
تستوحي هذه المقالة بشكل كبير من محتوى freeCodeCamp، ولكن بدلًا من مجرد مشاهدة الفيديوهات، ستقوم بإكمال المشاريع بنفسك. على مدار هذه السلسلة المصغرة من المقالات، ستبني خمسة مشاريع صغيرة. ولكل مشروع، هناك بعض القواعد الأساسية التي يجب اتباعها:
- يجب عليك كتابة الكود لجوانب معينة (أو جميعها) من الميزة المطلوبة.
- يجب عليك اجتياز الاختبارات المحددة للتحديات.
- يمكنك البحث عن مساعدة خارجية، ولكن نوصي بقضاء بعض الوقت مع الواجهة والتعليمات أولًا. تم تصميم الواجهة بناءً على كيفية قضائك لوقتك كمطور في أدوات التطوير الحقيقية.
ملاحظة هامة: يقوم codedamn بتشغيل نسخة خادم لكل مستخدم، لذلك لاستخدام الفصول الدراسية، تحتاج إلى التسجيل/تسجيل الدخول. إذا كنت ترغب فقط في مراجعة الكود والعمل على المشروع بنفسك خارج الفصل الدراسي، يمكنك الاطلاع عليه على GitHub. لقد أضفت روابط GitHub في كل قسم أدناه لتتمكن من الانتقال إلى الجزء ذي الصلة في الكود.
دعنا نبدأ بمشروعنا الأول! إذا تلقيت ملاحظات جيدة، سأستمر في كتابة المزيد من المقالات والمشاريع.
بناء تطبيق تذكير أعياد الميلاد (المشروع رقم 1)
نظرًا لأن هذا هو مشروعنا الأول، سنحافظ على مستوى تعقيد منخفض جدًا. في هذا المشروع، سنستخدم React لعرض قائمة من عناصر البيانات، وهي أعياد ميلاد بعض الأشخاص. سيتم عرض هذه البيانات من مصدر بيانات ثابت، ويجب أن يساعدك هذا في فهم كيفية استيراد واستخدام/مسح البيانات داخل متغير حالة (state).
سنعمل داخل فصل دراسي قمت بإنشائه على منصة Codedamn. يمكنك البدء في هذا الفصل الدراسي هنا. أنصح بشدة بإكمال هذا الفصل الدراسي والفصول الأخرى قدر الإمكان بنفسك. يمكنك (ويجب عليك) استخدام هذه المقالة كدليل.
إليك ما ستتعلمه في هذا الفصل الدراسي:
- كيف يبدو مشروع
Reactأساسي. - كيفية تحميل البيانات من ملف
JSثابت. - كيفية استخدام
useStateلتخزين البيانات. - كيفية مسح متغير الحالة (
state variable) ورؤية ذلك ينعكس في واجهة المستخدم (UI).
المختبر 1: مقدمة إلى المشروع

معاينة للمختبر حيث تكمل هذه المهمة.
إليك الرابط لهذا المختبر: هنا.
يقدم لك هذا التحدي الأول المشروع وبنيته. اقضِ بعض الوقت في تحديد جميع الأجزاء والمكونات ذات الصلة في هذا التحدي، وبمجرد الانتهاء، ما عليك سوى النقر على زر "Run Tests" لاجتياز هذا التحدي. لا يوجد شيء معقد هنا 🙂
المختبر 2: بناء حاوية عرض أعياد الميلاد

معاينة للمختبر حيث تكمل هذه المهمة.
إليك الرابط لهذا المختبر العملي: هنا. يمكنك أيضًا العثور على ملفات الإعداد للمختبر على GitHub هنا.
الآن بعد أن نظرت إلى كيفية تنظيم بنية المشروع والملفات، حان الوقت لإنشاء بعض العروض الثابتة. تذكر أنه يمكنك دائمًا إنشاء حاويات بيانات ثابتة أولًا ثم ملؤها ببيانات ديناميكية لاحقًا. هذه طريقة نظيفة جدًا لبناء مكونات ديناميكية، حيث تتيح لك تجهيز المكون قبل ملئه بالبيانات.
في هذا المختبر، لديك التحديات التالية لإكمالها:
- داخل ملف
App.jsxالخاص بك، قم بإنشاء التسلسل الهرمي لـHTMLالتالي:main > section.container > h3 + Listتلميح: الاختصار أعلاه يعني أن هيكلك يجب أن يبدو كالتالي:
<main> <section class="container"> <h3></h3> <List /> </section> </main> - يجب أن يحتوي وسم
h3الخاص بك على النص:0 birthdays today - يجب أن يكون مكون
<List />الخاص بك هو المكونList.jsxالذي تم استيراده في الأعلى.
لاجتياز جميع الاختبارات، تأكد من القيام بما يلي:
- يجب أن يكون هناك عنصر
'h3'واحد في ملفApp.jsxالخاص بك. - يجب أن يحتوي وسم
'h3'الخاص بك على"0 birthdays today"(بدون علامات اقتباس). - يجب عرض مكون
'List'الخاص بك.
إليك حل هذا التحدي:
import React, { useState } from 'react'
import data from './data'
import List from './List'
function App () {
// Edit your return statement here to match the instructions
return (
<main>
<section className="container">
<h3>0 birthdays today</h3>
<List />
</section>
</main>
)
}
export default App
المختبر 3: ملء قائمة البيانات الثابتة

معاينة للمختبر حيث تكمل هذه المهمة.
إليك الرابط لهذا المختبر: هنا. يمكنك أيضًا العثور على ملفات الإعداد للمختبر على GitHub هنا.
لدينا الآن واجهة المستخدم الأساسية جاهزة. دعنا الآن نملأ البيانات الثابتة من ملف data.js. تم فتح هذا الملف بالفعل لك على الجانب الأيمن من المحرر. تحقق من هذا الملف وشاهد كيف تبدو بيانات JSON.
في هذا المختبر، عليك القيام بالأشياء التالية:
- داخل ملف
App.jsxالخاص بك، يجب عليك الآن استبدال0 Birthdays Todayبـ<item count> Birthdays Today. لذلك، في البداية، يجب أن يظهر5 Birthdays Today. تذكر أن<item count>يأتي من عدد العناصر داخل متغيرdataالمستورد في الأعلى. تلميح: يمكنك استخدامdata.length. - مرر متغير
dataالمستورد كخاصية (prop) إلى مكونList. يجب أن تُسمى هذه الخاصيةpeople. تلميح:<List people={data} />. - في مكون
List، استخدم هذه البيانات الممررة لعرض أسماء الأشخاص فقط في الوقت الحالي. يمكنك استخدام دالةmapللتكرار على هؤلاء الأشخاص وعرض أسمائهم.
إليك 3 اختبارات يجب عليك اجتيازها:
- يجب أن يعرض ملف
App.jsxالخاص بك الآن"5 Birthdays Today"حيث يأتي الرقم"5"من طول العناصر المستوردة في الأعلى. - يجب أن تعرض شاشتك أسماء جميع الأشخاص في القائمة.
- يجب عليك استخدام خاصية
"people"في مكونListلتمرير البيانات ويجب أن تعرض الأسماء.
وإليك الحل لهذا التحدي.
ملف App.jsx:
import React, { useState } from 'react'
import data from './data'
import List from './List'
function App () {
return (
<main>
<section className="container">
{/* Make change to "0" here */}
<h3>{data.length} birthdays today</h3>
{/* pass data to list component */}
<List people={data} />
</section>
</main>
)
}
export default App
ملف List.jsx:
import React from 'react'
// accept props here
const List = (props) => {
const { people } = props
// Map over prop "people" and display only the names in any way you like
return people.map((item) => {
return <p key={item.id}> {item.name} </p>
})
}
export default List
المختبر 4: تحسين واجهة المستخدم وعرض التفاصيل

إليك رابط هذا المختبر: هنا. يمكنك أيضًا العثور على ملفات الإعداد للمختبر على GitHub هنا.
الآن بعد أن أصبح لدينا أسماء الأشخاص من البيانات الثابتة، دعنا نجعل واجهة المستخدم أفضل قليلًا. يمكنك مراجعة جميع ملفات CSS أولًا، ثم سنبدأ ببساطة في استخدام فئات CSS مباشرة. في هذا التحدي، عليك فقط البناء على التحدي الأخير وإنشاء واجهة مستخدم داخل مكون List.
في هذا المختبر، عليك القيام بالأشياء التالية:
- داخل ملف
List.jsxالخاص بك، قم بالتكرار على خاصيةpeopleواعرض هيكلHTMLالتالي:<article class="person"> <img src="<image of user>" alt="<name of user>" /> <div> <h4>NAME_OF_USER</h4> <p>AGE_OF_USER years</p> </div> </article> - تأكد من استبدال العناصر النائبة بشكل مناسب. تذكر أن فئات
CSSفيReact JSXتُسمىclassName!
إليك 4 اختبارات يجب عليك اجتيازها:
- يجب أن يعرض مكون
Listالخاص بك وسم"article"كعنصر أب. - يجب أن يعرض مكون
Listالخاص بك وسم"img"داخل وسم"article"معsrcوaltالصحيحين. - يجب أن يعرض مكون
Listالخاص بك"div > h4"داخل وسم"article"مع اسم الشخص. - يجب أن يعرض مكون
Listالخاص بك"div > p"داخل وسم"article"مع عمر الشخص.
وإليك الحل (ملف List.jsx):
import React from 'react'
// accept props here
const List = (props) => {
const { people } = props
// Map over prop "people" and code the right structure
return people.map((person) => {
const { id, name, age, image } = person
return (
<article key={id} className="person">
<img src={image} alt={name} />
<div>
<h4>{name}</h4>
<p>{age} years</p>
</div>
</article>
)
})
}
export default List
المختبر 5: إضافة زر “مسح الكل” لتفريغ القائمة

إليك رابط هذا المختبر: هنا. يمكنك أيضًا العثور على ملفات الإعداد للمختبر على GitHub هنا.
في هذا المختبر الأخير، دعنا الآن نضيف زر "Clear" الذي سيقوم بمسح جميع السجلات وإعادتها إلى 0 أعياد ميلاد. الزر متاح بالفعل لك، عليك فقط التأكد من أنه يعمل بشكل صحيح.
في هذا المختبر، عليك القيام بالأشياء التالية:
- إنشاء متغير حالة جديد يُسمى
people. - يجب أن تكون القيمة الأولية لمتغير الحالة هذا هي البيانات المستوردة من الأعلى.
- مرر متغير الحالة هذا الآن في مكون
List. - عند الضغط على زر
"Clear"، قم بتفريغ متغير الحالة بحيث لا يتم عرض أي سجل (تلميح: اضبطه على مصفوفة فارغة[]).
وهذه هي الاختبارات التي يجب عليك اجتيازها:
- يجب أن يكون هناك زر
"Clear All"على الشاشة (تم إنجازه لك بالفعل). - في البداية، يجب أن تكون جميع السجلات مرئية.
- عند الضغط على زر
"Clear All"، يجب أن يقوم بإزالة جميع السجلات من الشاشة.
إليك ملف حل App.jsx لهذا المختبر:
import React, { useState } from 'react'
import data from './data'
import List from './List'
function App () {
// create a state variable here
const [people, setPeople] = useState(data)
// this should clear all records
function clearAllRecords () {
setPeople([])
}
return (
<main>
<section className="container">
<h3>{people.length} birthdays today</h3>
<List people={people} />
<button onClick={clearAllRecords}>Clear All</button>
</section>
</main>
)
}
export default App
وهكذا تكون قد انتهيت! تهانينا على إكمال مشروع صغير في React. عمل رائع 🙂
الخلاصة
نأمل أن تكون قد استمتعت بهذا الفصل الدراسي على codedamn. يمكنك العثور على العديد من الفصول الأخرى في مسار تعلم React Mastery على codedamn. لا يزال هناك الكثير من الفجوات التي يجب ملؤها، ولكن هناك فرصة جيدة أن تبدأ بسلاسة تامة إذا كنت جديدًا في React. تأكد من إخباري كيف كانت تجربتك على حسابي في Twitter، حيث سيساعدني ذلك في صياغة الفصول الدراسية التدريبية التالية.
الخلاصة التقنية
يُعد هذا المشروع الصغير مقدمة ممتازة للمفاهيم الأساسية في مكتبة React.js. لقد أظهرنا بوضوح كيف يمكن للمطورين الجدد البدء في بناء واجهات مستخدم تفاعلية باستخدام مكونات React. التركيز على تحميل البيانات الثابتة، واستخدام خطاف useState لإدارة حالة التطبيق، وتمرير البيانات كخصائص (props) بين المكونات، يمثل حجر الزاوية في بناء تطبيقات React قابلة للتطوير والصيانة. كما أن إضافة وظيفة مسح البيانات تُبرز أهمية إدارة دورة حياة المكونات وتفاعلها مع المستخدم. هذه التجربة العملية لا تُعزز الفهم النظري فحسب، بل تُكسب المطور ثقة في قدرته على تحويل الأفكار إلى تطبيقات وظيفية، مما يجعله أساسًا متينًا للانتقال إلى مشاريع React أكثر تعقيدًا.