React: تتم إعادة عرض عناصر القائمة ذات "المفتاح" الفريد عند تغيير ترتيب العناصر.

تم إنشاؤها على ١٥ يوليو ٢٠١٨  ·  3تعليقات  ·  مصدر: facebook/react

هل تريد طلب ميزة أو الإبلاغ عن خطأ ؟
حشرة

ما هو السلوك الحالي؟
عند تقديم قائمة بالعناصر مع تعيين key كخاصية فريدة لكل عنصر عنصر ، إذا تغير ترتيب العناصر من العرض السابق ، تتم إعادة عرض عناصر العنصر التي تم تغيير فهارسها (يتم إنشاء مثيل جديد) بدلاً من re - استخدام مثيل موجود (تم تعيينه عبر مفتاح).

على سبيل المثال https://codesandbox.io/s/r5p48kzop
عرض قائمة boxes مع كل صندوق به عناصر id ، top ، left & color . كل 750ms نقوم بتحديث قيم ( top ، left ) لجميع العناصر داخل مصفوفة boxes .

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

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

إذا كان السلوك الحالي عبارة عن خطأ ، فالرجاء تقديم خطوات إعادة الإنتاج ، وإن أمكن عرضًا بسيطًا للمشكلة. الصق الرابط إلى JSFiddle (https://jsfiddle.net/Luktwrdm/) أو مثال CodeSandbox (https://codesandbox.io/s/new) أدناه:
https://codesandbox.io/s/r5p48kzop

ما هو السلوك المتوقع؟
بغض النظر عن ترتيب boxes ، يجب تحريك جميع عناصر الصندوق إلى مواقعها الجديدة نظرًا لأن لها خاصية فريدة key تعيينها عليها.

ما إصدارات React وأي متصفح / نظام تشغيل متأثر بهذه المشكلة؟
رد فعل 16.3.2 & 16.4.1 ، Chrome ، MacOS.

التعليق الأكثر فائدة

يا @ dhruvparmar372!

يبدو أن هذا تقييد لـ DOM. لإثبات ذلك ، قمت بإنشاء JSFiddle هذا الذي يغير ترتيب عقدتين من عقد DOM ثم يطبق فئة لبدء الانتقال.

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

أضفت القليل من الكود إلى CodeSandbox الخاص بك لجعله مرئيًا عند إعادة إنشاء مكون بواسطة React عن طريق تغيير <Box /> ليكون مكونًا للفصل وإنشاء معرف فريد في المُنشئ. كما ترى ، سيبقى المعرف ثابتًا: https://codesandbox.io/s/jn42wvl343

بالإضافة إلى ذلك ، قمت بتطبيق حل إعادة التدفق على المثال الخاص بك عن طريق تقسيم التحديث إلى قسمين setState s. الأول سوف يغير الترتيب ، ثم نقوم بإعادة التدفق ، وبعد ذلك نغير المركز. يبدو أن هذا يعمل بشكل جيد في Chrome و Firefox و Safari و Edge (لا يدعم CodeSandbox IE11 لذلك لم أتمكن من الاختبار على هذا المتصفح).

ال 3 كومينتر

يا @ dhruvparmar372!

يبدو أن هذا تقييد لـ DOM. لإثبات ذلك ، قمت بإنشاء JSFiddle هذا الذي يغير ترتيب عقدتين من عقد DOM ثم يطبق فئة لبدء الانتقال.

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

أضفت القليل من الكود إلى CodeSandbox الخاص بك لجعله مرئيًا عند إعادة إنشاء مكون بواسطة React عن طريق تغيير <Box /> ليكون مكونًا للفصل وإنشاء معرف فريد في المُنشئ. كما ترى ، سيبقى المعرف ثابتًا: https://codesandbox.io/s/jn42wvl343

بالإضافة إلى ذلك ، قمت بتطبيق حل إعادة التدفق على المثال الخاص بك عن طريق تقسيم التحديث إلى قسمين setState s. الأول سوف يغير الترتيب ، ثم نقوم بإعادة التدفق ، وبعد ذلك نغير المركز. يبدو أن هذا يعمل بشكل جيد في Chrome و Firefox و Safari و Edge (لا يدعم CodeSandbox IE11 لذلك لم أتمكن من الاختبار على هذا المتصفح).

مرحبا @ philipp-spiess شكرًا لتوضيح المشكلة وأمثلة الحل البديل.

مرحبًا @ philipp-spiess

لدي نفس المشكلة مع قائمة الفرز 😔
لسوء الحظ ، لم يعد مثال Codesandbox أعلاه يعمل بعد الآن (

هنا مثال:
https://jsfiddle.net/9odLvbrx/
يقوم بفرز العناصر عند النقر باستخدام انتقال بسيط لـ CSS.
تكمن المشكلة في أن الانتقال يظهر فقط على العنصر المحدد ويغفل باقي العناصر.

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

شكرا لك مقدما! 😊

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات