v19.2Latest

التفكير بطريقة React

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

ابدأ بالنموذج التخطيطي

تخيل أن لديك بالفعل واجهة برمجة تطبيقات JSON ونموذجًا تخطيطيًا من مصمم.

ترجع واجهة برمجة تطبيقات JSON بعض البيانات التي تبدو كالتالي:

يبدو النموذج التخطيطي كالتالي:

لتنفيذ واجهة مستخدم في React، ستتبع عادةً نفس الخطوات الخمس.

الخطوة 1: قسم واجهة المستخدم إلى تسلسل هرمي للمكونات

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

اعتمادًا على خلفيتك، يمكنك التفكير في تقسيم التصميم إلى مكونات بطرق مختلفة:

  • البرمجة—استخدم نفس التقنيات لتقرر ما إذا كان يجب إنشاء دالة أو كائن جديد. إحدى هذه التقنيات هيفصل الاهتمامات، أي أن المكون يجب أن يهتم بشكل مثالي بشيء واحد فقط. إذا نما في النهاية، فيجب تفكيكه إلى مكونات فرعية أصغر.
  • CSS—فكر فيما ستجعله محددات الفئات. (ومع ذلك، فإن المكونات أقل دقة قليلاً.)
  • التصميم—فكر في كيفية تنظيم طبقات التصميم.

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

هناك خمسة مكونات على هذه الشاشة:

  1. FilterableProductTable(رمادي) يحتوي على التطبيق بأكمله.
  2. SearchBar(أزرق) يستقبل مدخلات المستخدم.
  3. ProductTable(أرجواني فاتح) يعرض ويفرز القائمة وفقًا لمدخلات المستخدم.
  4. ProductCategoryRow(أخضر) يعرض عنوانًا لكل فئة.
  5. ProductRow(أصفر) يعرض صفًا لكل منتج.

إذا نظرت إلىProductTable(أرجواني فاتح)، ستلاحظ أن رأس الجدول (الذي يحتوي على تسميتي "الاسم" و"السعر") ليس مكونًا خاصًا به. هذه مسألة تفضيل، ويمكنك اختيار أي منهما. في هذا المثال، هو جزء منProductTableلأنه يظهر داخل قائمةProductTable. ومع ذلك، إذا أصبح هذا الرأس معقدًا (على سبيل المثال، إذا أضفت الفرز)، يمكنك نقله إلى مكونه الخاصProductTableHeader.

الآن بعد أن حددت المكونات في النموذج التخطيطي، رتبها في تسلسل هرمي. المكونات التي تظهر داخل مكون آخر في النموذج التخطيطي يجب أن تظهر كطفل في التسلسل الهرمي:

  • FilterableProductTable
    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

الخطوة 2: بناء نسخة ثابتة في React

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

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

يمكنك إما البناء "من الأعلى إلى الأسفل" عن طريق البدء ببناء المكونات الأعلى في التسلسل الهرمي (مثلFilterableProductTable) أو "من الأسفل إلى الأعلى" بالعمل من المكونات الأقل (مثلProductRow). في الأمثلة الأبسط، عادة ما يكون من الأسهل التوجه من الأعلى إلى الأسفل، وفي المشاريع الأكبر، يكون من الأسهل التوجه من الأسفل إلى الأعلى.

(إذا كان هذا الكود يبدو مخيفًا، فاطلع أولاً علىالبدء السريع!)

بعد بناء مكوناتك، سيكون لديك مكتبة من المكونات القابلة لإعادة الاستخدام والتي تعرض نموذج البيانات الخاص بك. نظرًا لأن هذا تطبيق ثابت، فإن المكونات ستعيد فقط JSX. المكون الموجود في أعلى التسلسل الهرمي (FilterableProductTable) سيأخذ نموذج البيانات الخاص بك كخاصية (prop). يُسمى هذاتدفق البيانات أحادي الاتجاهلأن البيانات تتدفق من المكون الأعلى مستوى إلى المكونات الموجودة في أسفل الشجرة.

مأزق

في هذه المرحلة، يجب ألا تستخدم أي قيم حالة (state). هذا مخصص للخطوة التالية!

الخطوة 3: ابحث عن التمثيل الأدنى والأكامل لحالة واجهة المستخدم

لجعل واجهة المستخدم تفاعلية، تحتاج إلى السماح للمستخدمين بتغيير نموذج البيانات الأساسي الخاص بك. ستستخدمالحالة (state)لهذا الغرض.

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

الآن فكر في جميع أجزاء البيانات في تطبيق المثال هذا:

  1. القائمة الأصلية للمنتجات
  2. نص البحث الذي أدخله المستخدم
  3. قيمة خانة الاختيار (checkbox)
  4. القائمة المفلترة للمنتجات

أي من هذه تعتبر حالة؟ حدد تلك التي ليست كذلك:

  • هل تبقى دون تغييرمع مرور الوقت؟ إذا كان الأمر كذلك، فهي ليست حالة.
  • هليتم تمريرها من مكون أبعبر الخصائص (props)؟ إذا كان الأمر كذلك، فهي ليست حالة.
  • هل يمكنك حسابهابناءً على حالة أو خصائص موجودة في مكونك؟ إذا كان الأمر كذلك، فهيبالتأكيدليست حالة!

ما تبقى هو على الأرجح حالة.

لنمر عليها واحدة تلو الأخرى مرة أخرى:

  1. القائمة الأصلية للمنتجاتيتم تمريرها كخصائص (props)، لذا فهي ليست حالة.
  2. يبدو أن نص البحث هو حالة لأنه يتغير مع مرور الوقت ولا يمكن حسابه من أي شيء آخر.
  3. يبدو أن قيمة خانة الاختيار (checkbox) هي حالة لأنها تتغير مع مرور الوقت ولا يمكن حسابها من أي شيء آخر.
  4. القائمة المفلترة للمنتجاتليست حالة لأنه يمكن حسابهاعن طريق أخذ القائمة الأصلية للمنتجات وتصفيتها وفقًا لنص البحث وقيمة خانة الاختيار.

هذا يعني أن نص البحث وقيمة خانة الاختيار فقط هما الحالة! أحسنت!

Deep Dive
الخاصيات مقابل الحالة

الخطوة 4: تحديد مكان تخزين الحالة

بعد تحديد الحد الأدنى من بيانات الحالة في تطبيقك، تحتاج إلى تحديد أي مكون مسؤول عن تغيير هذه الحالة، أويملكالحالة. تذكر: يستخدم React تدفق البيانات أحادي الاتجاه، حيث يتم تمرير البيانات إلى أسفل تسلسل المكونات من المكون الأب إلى المكون الابن. قد لا يكون واضحًا على الفور أي مكون يجب أن يملك أي حالة. يمكن أن يكون هذا تحديًا إذا كنت جديدًا على هذا المفهوم، ولكن يمكنك اكتشافه باتباع هذه الخطوات!

لكل جزء من الحالة في تطبيقك:

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

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

الآن دعنا نطبق استراتيجيتنا عليهما:

  1. حدد المكونات التي تستخدم الحالة:
    • ProductTableيحتاج إلى تصفية قائمة المنتجات بناءً على تلك الحالة (نص البحث وقيمة خانة الاختيار).
    • SearchBarيحتاج إلى عرض تلك الحالة (نص البحث وقيمة خانة الاختيار).
  2. ابحث عن المكون الأب المشترك:أول مكون أب مشترك بين كلا المكونين هوFilterableProductTable.
  3. قرر أين تعيش الحالة: سنحتفظ بقيم نص التصفية وحالة التحديد فيFilterableProductTable.

لذا ستوجد قيم الحالة فيFilterableProductTable.

أضف الحالة إلى المكون باستخدامخطاف useState().الخطاطيف (Hooks) هي دوال خاصة تسمح لك "بالاتصال بـ" React. أضف متغيري حالة في أعلى مكونFilterableProductTableوحدد حالتهما الأولية:

ثم، مررfilterText و inStockOnlyإلىProductTable و SearchBarكخاصيات:

يمكنك البدء في رؤية كيف سيتصرف تطبيقك. قم بتعديل القيمة الأولية لـfilterText من useState('')إلىuseState('fruit')في الكود الموجود في صندوق التجربة أدناه. ستلاحظ تحديث نص إدخال البحث والجدول معًا:

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

وحدة التحكم

لقد قدمت خاصية `value` لحقل نموذج بدون معالج `onChange`. هذا سيعرض حقلًا للقراءة فقط.

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

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

الخطوة 5: إضافة تدفق البيانات العكسي

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

تجعل React تدفق البيانات هذا صريحًا، لكنه يتطلب كتابة أكثر قليلًا من الربط ثنائي الاتجاه للبيانات. إذا حاولت الكتابة أو تحديد مربع الاختيار في المثال أعلاه، ستلاحظ أن React تتجاهل إدخالك. هذا مقصود. بكتابة<input value={filterText} />، قمت بتعيين خاصيةvalueلعنصرinputلتكون دائمًا مساوية لحالةfilterTextالممررة منFilterableProductTable. نظرًا لأن حالةfilterTextلم يتم تعيينها أبدًا، فإن الإدخال لا يتغير.

تريد جعل الأمر بحيث كلما قام المستخدم بتغيير مدخلات النموذج، يتم تحديث الحالة لتعكس تلك التغييرات. الحالة مملوكة لـFilterableProductTable، لذا فقط هي يمكنها استدعاءsetFilterText و setInStockOnly. للسماح لـSearchBarبتحديث حالةFilterableProductTable، تحتاج إلى تمرير هذه الدوال إلىSearchBar:

داخلSearchBar، ستضيف معالجات حدثonChangeوتعين الحالة الأصلية منها:

الآن التطبيق يعمل بالكامل!

يمكنك التعرف على كل ما يتعلق بمعالجة الأحداث وتحديث الحالة في قسمإضافة التفاعلية.

إلى أين تذهب من هنا

كانت هذه مقدمة موجزة جدًا حول كيفية التفكير في بناء المكونات والتطبيقات باستخدام React. يمكنكبدء مشروع Reactالآن أوالغوص أعمق في جميع الصيغ النحويةالمستخدمة في هذا البرنامج التعليمي.