v19.2Latest

الحالة: ذاكرة المكون

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

سوف تتعلم
  • كيفية إضافة متغير حالة باستخدام خطافuseState
  • ما هي زوج القيم التي يُرجعها خطافuseState
  • كيفية إضافة أكثر من متغير حالة واحد
  • لماذا تُسمى الحالة محلية

عندما لا يكون المتغير العادي كافيًا

إليك مكونًا يعرض صورة منحوتة. يجب أن يؤدي النقر على زر "التالي" إلى عرض المنحوتة التالية عن طريق تغييرindexإلى1، ثم2، وهكذا. ومع ذلك، هذالن يعمل(يمكنك تجربته!):

معالج الحدثhandleClickيقوم بتحديث متغير محلي،index. لكن شيئين يمنعان هذا التغيير من أن يكون مرئيًا:

  1. المتغيرات المحلية لا تستمر بين عمليات التصيير.عندما يقوم React بتصيير هذا المكون للمرة الثانية، فإنه يصييره من البداية — فهو لا يأخذ في الاعتبار أي تغييرات في المتغيرات المحلية.
  2. التغييرات في المتغيرات المحلية لن تُطلق عمليات تصيير.React لا يدرك أنه يحتاج إلى تصيير المكون مرة أخرى بالبيانات الجديدة.

لتحديث مكون ببيانات جديدة، يجب أن يحدث شيئان:

  1. الاحتفاظبالبيانات بين عمليات التصيير.
  2. تشغيلReact لتصيير المكون ببيانات جديدة (إعادة التصيير).

يوفر خطافuseStateهذين الأمرين:

  1. متغيرحالةللاحتفاظ بالبيانات بين عمليات التصيير.
  2. دالةضبط الحالةلتحديث المتغير وتشغيل React لتصيير المكون مرة أخرى.

إضافة متغير حالة

لإضافة متغير حالة، استوردuseStateمن React في أعلى الملف:

ثم، استبدل هذا السطر:

بـ

indexهو متغير حالة وsetIndexهي دالة الضبط.

بناء الجملة[ و ]هنا يسمىتفكيك المصفوفةويتيح لك قراءة القيم من مصفوفة. المصفوفة التي تُرجعهاuseStateتحتوي دائمًا على عنصرين بالضبط.

هذه هي طريقة عملهما معًا فيhandleClick:

الآن، النقر على زر "التالي" يبدل المنحوتة الحالية:

التقِ بأول خطاف لك

في React، تُسمى الدالةuseState، وأي دالة أخرى تبدأ بـ "use"، بـ خطاف (Hook).

الخطافاتهي دوال خاصة تكون متاحة فقط أثناءالتصييرفي React (وهو ما سنتعمق فيه أكثر في الصفحة التالية). تتيح لك "التعليق" بميزات React المختلفة.

الحالة هي مجرد واحدة من تلك الميزات، لكنك ستلتقي بالخطافات الأخرى لاحقًا.

مأزق

الخطافات—الدوال التي تبدأ بـuse—لا يمكن استدعاؤها إلا في المستوى الأعلى لمكوناتك أوخطافاتك الخاصة.لا يمكنك استدعاء الخطافات داخل الشروط أو الحلقات أو الدوال المتداخلة الأخرى. الخطافات هي دوال، لكن من المفيد التفكير فيها كإعلانات غير مشروطة عن احتياجات مكونك. أنت "تستخدم" ميزات React في أعلى مكونك بشكل مشابه لكيفية "استيراد" الوحدات في أعلى ملفك.

تشريحuseState

عند استدعائك لـuseState، فإنك تخبر React أنك تريد أن يتذكر هذا المكون شيئًا ما:

في هذه الحالة، تريد أن يتذكر Reactindex.

ملاحظة

العُرف هو تسمية هذا الزوج مثلconst [something, setSomething]. يمكنك تسميته بأي شيء تريده، لكن العُرف يجعل الأمور أسهل للفهم عبر المشاريع.

الوسيط الوحيد لـuseState هو القيمة الابتدائيةلمتغير الحالة لديك. في هذا المثال، تم تعيين القيمة الابتدائية لـindex إلى 0باستخدامuseState(0).

في كل مرة يُصيَّر مكونك، تمنحكuseStateمصفوفة تحتوي على قيمتين:

  1. متغيرالحالة(index) بالقيمة التي قمت بتخزينها.
  2. دالةتعيين الحالة(setIndex) والتي يمكنها تحديث متغير الحالة وتشغيل React لتصيير المكون مرة أخرى.

إليك كيف يحدث ذلك عمليًا:

  1. يتم تصيير مكونك لأول مرة.لأنك مررت0إلىuseStateكقيمة أولية لـindex، سترجع[0, setIndex]. يتذكر React أن0هي أحدث قيمة للحالة.
  2. تقوم بتحديث الحالة.عندما ينقر المستخدم على الزر، يتم استدعاءsetIndex(index + 1).indexهي0، لذا فهيsetIndex(1). هذا يخبر React أن يتذكر أنindexهي الآن1ويشغل تصييرًا آخر.
  3. التصيير الثاني لمكونك.لا يزال React يرىuseState(0)، ولكن لأن Reactيتذكرأنك عينتindexإلى1، فإنه يرجع[1, setIndex]بدلاً من ذلك.
  4. وهكذا دواليك!

إعطاء مكون عدة متغيرات حالة

يمكنك الحصول على العديد من متغيرات الحالة من العديد من الأنواع كما تريد في مكون واحد. يحتوي هذا المكون على متغيري حالة، رقمindexوقيمة منطقيةshowMoreيتم تبديلها عند النقر على "إظهار التفاصيل":

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

الحالة معزولة وخاصة

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

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

هذا ما يجعل الحالة مختلفة عن المتغيرات العادية التي قد تعلن عنها في أعلى الموديول الخاص بك. الحالة ليست مرتبطة باستدعاء دالة معين أو مكان في الكود، بل هي "محلية" للمكان المحدد على الشاشة. لقد قمت بتصيير مكونين<Gallery />، لذا يتم تخزين حالتهما بشكل منفصل.

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

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

ملخص

  • استخدم متغير حالة عندما يحتاج المكون إلى "تذكر" بعض المعلومات بين عمليات التصيير.
  • يتم تعريف متغيرات الحالة عن طريق استدعاء خطافuseState.
  • الخطاطيف هي دوال خاصة تبدأ بـuse. تتيح لك "الخطف" إلى ميزات React مثل الحالة.
  • قد تذكرك الخطاطيف بعمليات الاستيراد: يجب استدعاؤها دون شروط. استدعاء الخطاطيف، بما في ذلكuseState، يكون صالحًا فقط في المستوى الأعلى للمكون أو خطاف آخر.
  • يُرجع خطافuseStateزوجًا من القيم: الحالة الحالية والدالة لتحديثها.
  • يمكن أن يكون لديك أكثر من متغير حالة. داخليًا، يطابق React بينها حسب ترتيبها.
  • الحالة خاصة بالمكون. إذا قمت بتصييره في مكانين، يحصل كل نسخة على حالتها الخاصة.

Try out some challenges

When you press “Next” on the last sculpture, the code crashes. Fix the logic to prevent the crash. You may do this by adding extra logic to event handler or by disabling the button when the action is not possible.

After fixing the crash, add a “Previous” button that shows the previous sculpture. It shouldn’t crash on the first sculpture.