v19.2Latest

الحفاظ على الحالة وإعادة تعيينها

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

سوف تتعلم
  • متى يختار React الحفاظ على الحالة أو إعادة تعيينها
  • كيفية إجبار React على إعادة تعيين حالة المكون
  • كيف تؤثر المفاتيح والأنواع على ما إذا كانت الحالة محفوظة أم لا

الحالة مرتبطة بموقع في شجرة التصيير

يبني Reactأشجار التصييرلهيكل المكونات في واجهة المستخدم الخاصة بك.

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

هنا، يوجد علامة JSX واحدة فقط<Counter />، لكنها مُصَيرة في موقعين مختلفين:

هذا هو شكلها كشجرة:

مخطط لشجرة مكونات React. عقدة الجذر مُوسومة بـ 'div' ولها طفلان. كل طفل مُوسوم بـ 'Counter' ويحتوي كلاهما على فقاعة حالة مُوسومة بـ 'count' بقيمة 0.مخطط لشجرة مكونات React. عقدة الجذر مُوسومة بـ 'div' ولها طفلان. كل طفل مُوسوم بـ 'Counter' ويحتوي كلاهما على فقاعة حالة مُوسومة بـ 'count' بقيمة 0.

شجرة React

هذان عدادان منفصلان لأن كل منهما مُصَير في موقعه الخاص في الشجرة.لا تحتاج عادةً إلى التفكير في هذه المواقع لاستخدام React، لكن فهم كيفية عملها يمكن أن يكون مفيدًا.

في React، كل مكون على الشاشة له حالة معزولة تمامًا. على سبيل المثال، إذا صَيرت مكونينCounterجنبًا إلى جنب، سيكون لكل منهما حالته الخاصة والمستقلة،score و hover.

جرب النقر على كلا العدادين ولاحظ أنهما لا يؤثران على بعضهما البعض:

كما ترى، عند تحديث عداد واحد، يتم تحديث حالة ذلك المكون فقط:

مخطط لشجرة مكونات React. عقدة الجذر مُوسومة بـ 'div' ولها طفلان. الطفل الأيسر مُوسوم بـ 'Counter' ويحتوي على فقاعة حالة مُوسومة بـ 'count' بقيمة 0. الطفل الأيمن مُوسوم بـ 'Counter' ويحتوي على فقاعة حالة مُوسومة بـ 'count' بقيمة 1. فقاعة حالة الطفل الأيمن مظللة باللون الأصفر للإشارة إلى أن قيمتها تم تحديثها.مخطط لشجرة مكونات React. عقدة الجذر مُوسومة بـ 'div' ولها طفلان. الطفل الأيسر مُوسوم بـ 'Counter' ويحتوي على فقاعة حالة مُوسومة بـ 'count' بقيمة 0. الطفل الأيمن مُوسوم بـ 'Counter' ويحتوي على فقاعة حالة مُوسومة بـ 'count' بقيمة 1. فقاعة حالة الطفل الأيمن مظللة باللون الأصفر للإشارة إلى أن قيمتها تم تحديثها.

تحديث الحالة

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

لاحظ كيف تختفي حالة العداد الثاني تمامًا في اللحظة التي تتوقف فيها عن تصييره. هذا لأنه عندما يزيل React مكونًا، فإنه يدمر حالته.

مخطط لشجرة مكونات React. عقدة الجذر مُوسومة بـ 'div' ولها طفلان. الطفل الأيسر مُوسوم بـ 'Counter' ويحتوي على فقاعة حالة مُوسومة بـ 'count' بقيمة 0. الطفل الأيمن مفقود، وفي مكانه صورة 'poof' صفراء، تسلط الضوء على المكون الذي يتم حذفه من الشجرة.مخطط لشجرة مكونات React. العقدة الجذرية تحمل تسمية 'div' ولها طفلان. الطفل الأيسر يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' بقيمة 0. الطفل الأيمن مفقود، وفي مكانه صورة 'poof' صفراء، تسلط الضوء على المكون المحذوف من الشجرة.

حذف مكون

عند تحديد خانة الاختيار "عرض العداد الثاني"، يتم تهيئة عداد ثانيCounterوحالته من الصفر (score = 0) وإضافته إلى DOM.

مخطط لشجرة مكونات React. العقدة الجذرية تحمل تسمية 'div' ولها طفلان. الطفل الأيسر يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' بقيمة 0. الطفل الأيمن يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' بقيمة 0. العقدة الطفل اليمنى بأكملها مظللة باللون الأصفر، مما يشير إلى أنها أضيفت للتو إلى الشجرة.مخطط لشجرة مكونات React. العقدة الجذرية تحمل تسمية 'div' ولها طفلان. الطفل الأيسر يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' بقيمة 0. الطفل الأيمن يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' بقيمة 0. العقدة الطفل اليمنى بأكملها مظللة باللون الأصفر، مما يشير إلى أنها أضيفت للتو إلى الشجرة.

إضافة مكون

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

المكون نفسه في نفس الموضع يحافظ على الحالة

في هذا المثال، هناك علامتان مختلفتان<Counter />:

عند تحديد خانة الاختيار أو مسحها، لا تتم إعادة تعيين حالة العداد. سواء كانت قيمةisFancy trueأمfalse، لديك دائمًا<Counter />كالطفل الأول لعنصرdivالذي تُرجع من المكون الجذريApp:

مخطط مقسم إلى قسمين يفصل بينهما سهم انتقالي. يحتوي كل قسم على تخطيط للمكونات مع مكون أب يحمل تسمية 'App' يحتوي على فقاعة حالة تحمل تسمية isFancy. هذا المكون له طفل واحد يحمل تسمية 'div'، والذي يؤدي إلى فقاعة خاصية تحتوي على isFancy (مظللة باللون البنفسجي) يتم تمريرها إلى الطفل الوحيد. الطفل الأخير يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' وقيمة 3 في كلا المخططين. في القسم الأيسر من المخطط، لا يوجد شيء مظلل وقيمة حالة الأب isFancy هي false. في القسم الأيمن من المخطط، تغيرت قيمة حالة الأب isFancy إلى true وهي مظللة باللون الأصفر، وكذلك فقاعة الخاصية أدناه، والتي تغيرت قيمتها isFancy أيضًا إلى true.مخطط مقسم إلى قسمين يفصل بينهما سهم انتقالي. يحتوي كل قسم على تخطيط للمكونات مع مكون أب يحمل تسمية 'App' يحتوي على فقاعة حالة تحمل تسمية isFancy. هذا المكون له طفل واحد يحمل تسمية 'div'، والذي يؤدي إلى فقاعة خاصية تحتوي على isFancy (مظللة باللون البنفسجي) يتم تمريرها إلى الطفل الوحيد. الطفل الأخير يحمل تسمية 'Counter' ويحتوي على فقاعة حالة تحمل تسمية 'count' وقيمة 3 في كلا المخططين. في القسم الأيسر من المخطط، لا يوجد شيء مظلل وقيمة حالة الأب isFancy هي false. في القسم الأيمن من المخطط، تغيرت قيمة حالة الأب isFancy إلى true وهي مظللة باللون الأصفر، وكذلك فقاعة الخاصية أدناه، والتي تغيرت قيمتها isFancy أيضًا إلى true.

تحديث حالةAppلا يعيد تعيينCounterلأنCounterيبقى في نفس الموضع

إنه نفس المكون في نفس الموضع، لذا من منظور React، إنه نفس العداد.

مأزق

تذكر أنالموضع في شجرة واجهة المستخدم—وليس في ترميز JSX—هو ما يهم React!هذا المكون لهreturnشرطان مختلفان يحويان علامات<Counter />JSX داخل وخارجif:

قد تتوقع إعادة تعيين الحالة عند تحديد خانة الاختيار، لكن هذا لا يحدث! هذا لأنكلتا علامتي<Counter />هاتين تُعرضان في نفس الموضع.لا يعرف React أين تضع الشروط في دالتك. كل ما "يراه" هو الشجرة التي تُرجعها.

في كلتا الحالتين، يُرجع مكونApp عنصر <div>يحتوي على<Counter />كطفل أول. بالنسبة لـ React، هذان العدادان لهما نفس "العنوان": الطفل الأول للطفل الأول من الجذر. هذه هي الطريقة التي يطابق بها React بينهما في التقديمات السابقة والتالية، بغض النظر عن كيفية هيكلة منطقك.

مكونات مختلفة في نفس الموضع تعيد تعيين الحالة

في هذا المثال، سيؤدي تحديد خانة الاختيار إلى استبدال<Counter>بعنصر<p>:

هنا، تقوم بالتبديل بينأنواعمختلفةمكوناتفي نفس الموضع<div>يحتوي على مكونCounter. ولكن عندما استبدلته بعنصرp، قام React بإزالة مكونCounter من شجرة واجهة المستخدم وتدمير حالته.

مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع طفل واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 3. القسم الأوسط له نفس الأصل 'div'، ولكن مكون الطفل قد تم حذفه الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'p'، مظلل باللون الأصفر.مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع طفل واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 3. القسم الأوسط له نفس الأصل 'div'، ولكن مكون الطفل قد تم حذفه الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'p'، مظلل باللون الأصفر.

عندما يتغيرCounter إلى p، يتم حذفCounterوإضافةp

مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'p'. القسم الأوسط له نفس الأصل 'div'، ولكن مكون الطفل قد تم حذفه الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، مظلل باللون الأصفر.مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'p'. القسم الأوسط له نفس الأصل 'div'، ولكن مكون الطفل قد تم حذفه الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، مظلل باللون الأصفر.

عند العودة للتبديل، يتم حذفpوإضافةCounter

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

يتم إعادة تعيين حالة العداد عند النقر على خانة الاختيار. على الرغم من أنك تعرض مكونCounter، فإن الطفل الأول لعنصرdivيتغير منsectionإلىdiv. عندما تمت إزالة الطفلsectionمن DOM، تم تدمير الشجرة بأكملها تحته (بما في ذلك مكونCounterوحالته) أيضًا.

مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع طفل واحد مسمى 'section'، والذي له طفل واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 3. القسم الأوسط له نفس الأصل 'div'، ولكن مكونات الطفل قد تم حذفها الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'div'، مظلل باللون الأصفر، أيضًا مع طفل جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، كلها مظللة باللون الأصفر.مخطط مكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع طفل واحد مسمى 'section'، والذي له طفل واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 3. القسم الأوسط له نفس الأصل 'div'، ولكن مكونات الطفل قد تم حذفها الآن، كما هو موضح بصورة 'إثبات' صفراء. القسم الثالث له نفس الأصل 'div' مرة أخرى، الآن مع طفل جديد مسمى 'div'، مظلل باللون الأصفر، أيضًا مع طفل جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، كلها مظللة باللون الأصفر.

عندما يتغيرsection إلى div، يتم حذفsection وإضافة divالجديد

مخطط يتكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع ابن واحد مسمى 'div'، والذي له ابن واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0. القسم الأوسط له نفس الأب 'div'، لكن المكونات الفرعية قد حُذفت الآن، كما هو موضح بصورة 'proof' صفراء. القسم الثالث له نفس الأب 'div' مرة أخرى، الآن مع ابن جديد مسمى 'section'، مظلل باللون الأصفر، وأيضًا مع ابن جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، كلها مظللة باللون الأصفر.مخطط يتكون من ثلاثة أقسام، مع سهم ينتقل بين كل قسم. القسم الأول يحتوي على مكون React مسمى 'div' مع ابن واحد مسمى 'div'، والذي له ابن واحد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0. القسم الأوسط له نفس الأب 'div'، لكن المكونات الفرعية قد حُذفت الآن، كما هو موضح بصورة 'proof' صفراء. القسم الثالث له نفس الأب 'div' مرة أخرى، الآن مع ابن جديد مسمى 'section'، مظلل باللون الأصفر، وأيضًا مع ابن جديد مسمى 'Counter' يحتوي على فقاعة حالة مسمى 'count' بقيمة 0، كلها مظللة باللون الأصفر.

عند العودة للتبديل، يتم حذفdivويتم إضافةsectionالجديد

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

مأزق

لهذا السبب لا يجب عليك تداخل تعريفات دوال المكونات.

هنا، تم تعريف دالة مكونMyTextField داخلMyComponent:

في كل مرة تنقر على الزر، تختفي حالة الإدخال! هذا لأن دالةمختلفةMyTextFieldيتم إنشاؤها لكل عملية تصيير لـMyComponent. أنت تصيّر مكونًامختلفًافي نفس الموضع، لذا يقوم React بإعادة تعيين كل الحالة الموجودة تحته. هذا يؤدي إلى أخطاء ومشاكل في الأداء. لتجنب هذه المشكلة،قم دائمًا بتعريف دوال المكونات في المستوى الأعلى، ولا تتداخل تعريفاتها.

إعادة تعيين الحالة في نفس الموضع

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

حاليًا، عند تغيير اللاعب، يتم الحفاظ على النتيجة. يظهر المكونانCounterفي نفس الموضع، لذا يرى React أنهمانفسCounterالذي تغيرت خاصيةpersonالخاصة به.

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

هناك طريقتان لإعادة تعيين الحالة عند التبديل بينهما:

  1. تصيير المكونات في مواضع مختلفة
  2. إعطاء كل مكون هوية صريحة باستخدامkey

الخيار 1: تصيير مكون في مواضع مختلفة

إذا كنت تريد أن يكون هذان العدادانCounterمستقلين، يمكنك تصييرهما في موضعين مختلفين:

  • في البداية،isPlayerAهيtrue. لذا فإن الموضع الأول يحتوي على حالةCounter، والثاني فارغ.
  • عند النقر على زر "اللاعب التالي"، يتم مسح الموضع الأول ولكن الموضع الثاني يحتوي الآن علىCounter.
مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'true'. المكون الابن الوحيد، المرتب على اليسار، مُسمى Counter مع فقاعة حالة مُسماة 'count' وقيمة 0. كل المكون الابن على اليسار مُظلل باللون الأصفر، مما يشير إلى أنه تمت إضافته.مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'true'. المكون الابن الوحيد، المرتب على اليسار، مُسمى Counter مع فقاعة حالة مُسماة 'count' وقيمة 0. كل المكون الابن على اليسار مُظلل باللون الأصفر، مما يشير إلى أنه تمت إضافته.

الحالة الابتدائية

مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'false'. فقاعة الحالة مُظللة باللون الأصفر، مما يشير إلى أنها تغيرت. المكون الابن على اليسار تم استبداله بصورة 'poof' صفراء تشير إلى أنه تم حذفه وهناك مكون ابن جديد على اليمين، مُظلل باللون الأصفر مما يشير إلى أنه تمت إضافته. المكون الابن الجديد مُسمى 'Counter' ويحتوي على فقاعة حالة مُسماة 'count' بقيمة 0.مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'false'. فقاعة الحالة مُظللة باللون الأصفر، مما يشير إلى أنها تغيرت. المكون الابن على اليسار تم استبداله بصورة 'poof' صفراء تشير إلى أنه تم حذفه وهناك مكون ابن جديد على اليمين، مُظلل باللون الأصفر مما يشير إلى أنه تمت إضافته. المكون الابن الجديد مُسمى 'Counter' ويحتوي على فقاعة حالة مُسماة 'count' بقيمة 0.

النقر على "التالي"

مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'true'. فقاعة الحالة مُظللة باللون الأصفر، مما يشير إلى أنها تغيرت. هناك مكون ابن جديد على اليسار، مُظلل باللون الأصفر مما يشير إلى أنه تمت إضافته. المكون الابن الجديد مُسمى 'Counter' ويحتوي على فقاعة حالة مُسماة 'count' بقيمة 0. المكون الابن على اليمين تم استبداله بصورة 'poof' صفراء تشير إلى أنه تم حذفه.مخطط بهيكل شجرة لمكونات React. المكون الأصل مُسمى 'Scoreboard' مع فقاعة حالة مُسماة isPlayerA بقيمة 'true'. فقاعة الحالة مُظللة باللون الأصفر، مما يشير إلى أنها تغيرت. هناك مكون ابن جديد على اليسار، مُظلل باللون الأصفر مما يشير إلى أنه تمت إضافته. المكون الابن الجديد مُسمى 'Counter' ويحتوي على فقاعة حالة مُسماة 'count' بقيمة 0. المكون الابن على اليمين تم استبداله بصورة 'poof' صفراء تشير إلى أنه تم حذفه.

النقر على "التالي" مرة أخرى

يتم تدمير حالة كلCounterفي كل مرة يتم إزالته من DOM. وهذا هو السبب في إعادة تعيينها في كل مرة تنقر فيها على الزر.

هذا الحل مناسب عندما يكون لديك عدد قليل فقط من المكونات المستقلة المعروضة في نفس المكان. في هذا المثال، لديك اثنان فقط، لذا ليس من الصعب عرضهما بشكل منفصل في JSX.

الخيار 2: إعادة تعيين الحالة باستخدام مفتاح

هناك أيضًا طريقة أخرى وأكثر عمومية لإعادة تعيين حالة المكون.

ربما رأيتkeys عندعرض القوائم.المفاتيح ليست فقط للقوائم! يمكنك استخدام المفاتيح لجعل React يميز بين أي مكونات. بشكل افتراضي، يستخدم React الترتيب داخل الأصل ("العداد الأول"، "العداد الثاني") للتمييز بين المكونات. لكن المفاتيح تتيح لك إخبار React بأن هذا ليس مجردأولعداد، أوثانيعداد، بل عداد محدد — على سبيل المثال، عدادتايلور. بهذه الطريقة، ستعرف React عدادتايلورأينما ظهر في الشجرة!

في هذا المثال، لا تشارك العدادان<Counter />الحالة حتى وإن ظهرا في نفس المكان في JSX:

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

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

ملاحظة

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

إعادة تعيين نموذج باستخدام مفتاح

إعادة تعيين الحالة باستخدام مفتاح مفيدة بشكل خاص عند التعامل مع النماذج.

في تطبيق الدردشة هذا، يحتوي مكون<Chat>على حالة إدخال النص:

جرب إدخال شيء في حقل الإدخال، ثم اضغط على "أليس" أو "بوب" لاختيار مستلم مختلف. ستلاحظ أن حالة الإدخال محفوظة لأن<Chat>يتم عرضه في نفس الموضع في الشجرة.

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

هذا يضمن أنه عند اختيار مستلم مختلف، سيتم إعادة إنشاء مكونChatمن الصفر، بما في ذلك أي حالة في الشجرة أسفله. سيقوم React أيضًا بإعادة إنشاء عناصر DOM بدلاً من إعادة استخدامها.

الآن، تبديل المستلم يمسح دائمًا حقل النص:

Deep Dive
الحفاظ على الحالة للمكونات المُزالَة

ملخص

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

Try out some challenges

Challenge 1 of 5:Fix disappearing input text #

This example shows a message when you press the button. However, pressing the button also accidentally resets the input. Why does this happen? Fix it so that pressing the button does not reset the input text.