محتويات الدورة

React Native / الأوصاف الأصلية والتفاعل المحلي / الدرس 6

هوية FlatList والاختيار ذو العمر الواضح

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

وقت القراءة التقريبي: 4 دقيقةتاريخ مراجعة المحتوى
في هذه الصفحة

أهداف الدرس

  • موضع الصف ليس هوية السجل
  • أظهر الاعتماديات خارج مصفوفة البيانات
  • سوِّ اختفاء المعرّفات وفقا لسياسة معلنة

موضع الصف ليس هوية السجل

يغير الترشيح والفرز والإدراج والصفحات موضع العنصر دون تغيير السجل الذي يمثله. خزّن الاختيار بمعرّف مجال مستقر بدلا من فهرس مصفوفة. ليست التسمية مفتاحا آمنا دائما لأن العناوين قد تتغير أو تتكرر. ينبغي أن يعيد keyExtractor في FlatList نصا فريدا مستقرا للعناصر الشقيقة. المعرّفات المكررة عيب عند حدود البيانات يجب رفضه أو حله قبل العرض. لا تولد مفتاحا عشوائيا جديدا في كل عرض لإزالة تحذير؛ فهو يستبدل الهوية وقد يصفر حالة الصف بدلا من حفظها.

أظهر الاعتماديات خارج مصفوفة البيانات

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

jsx وحدة توضيحية من React Native؛ تتطلب بيئة التطبيق المتوافقة المبيّنة.
import {useState} from 'react';
import {FlatList, Pressable, Text} from 'react-native';
const workshops = [{id: 'w-7', title: 'Maps'}, {id: 'w-9', title: 'Rivers'}];
export default function App() {
  const [selected, setSelected] = useState([]);
  return <FlatList data={workshops} extraData={selected}
    keyExtractor={item => item.id}
    renderItem={({item}) => <Pressable accessibilityRole="button"
      accessibilityState={{selected: selected.includes(item.id)}}
      onPress={() => setSelected(previous => previous.includes(item.id)
        ? previous.filter(id => id !== item.id) : [...previous, item.id])}>
      <Text>{item.title}{selected.includes(item.id) ? ' selected' : ''}</Text>
    </Pressable>} />;
}
الناتج المتوقع
Initially Maps and Rivers; selecting w-7 predicts Maps selected while Rivers stays unchanged.

يملك المستوى فوق الصفوف الاختيار بمعرّف السجل. ويجعل extraData اعتماد العرض الخارجي صريحا.

سوِّ اختفاء المعرّفات وفقا لسياسة معلنة

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

javascript نموذج JavaScript مستقل بمدخلات محلية مصطنعة.
function retainVisibleSelection(selected, rows) {
  const visible = new Set(rows.map(row => row.id));
  return selected.filter(id => visible.has(id));
}
const before = ['w-7', 'w-9'];
const after = retainVisibleSelection(before, [{id: 'w-9'}, {id: 'w-11'}]);
console.log(JSON.stringify(after));
console.log(JSON.stringify(before));
الناتج المتوقع
["w-9"]
["w-7","w-9"]

تبقى w-9 فقط بسياسة الصفحة المحلية. ولا تتغير اللقطة الأصلية أو يعاد تفسير سجل بموضعه.

يغير العرض الافتراضي عمر الصف

قد تزيل قائمة افتراضية صفوفا خارج الشاشة ثم تعرضها مجددا لاحقا. لذلك تحتاج المسودات الدائمة واختيارات المجال إلى مالك خارج الصف المنفرد، ما لم يكن فقدها مقصودا. ويتبادل FlatList الذاكرة والاستجابة مع سلوك نافذة العرض؛ فلا تنسخ إعدادات عامة للنافذة أو الدفعات دون قياس الهدف الفعلي. يفيد getItemLayout عندما تكون أبعاد الصف معلومة حقا، لكن الإزاحات غير الدقيقة قد تكسر التمرير، خصوصا مع النص الديناميكي والفواصل. ScrollView كبير يعرض كل الصفوف مسبقا حمل مختلف، وليس إصلاحا مكافئا لأعراض العرض الافتراضي.

اختبر الانتقال والعمر لا التسميات الظاهرة فقط

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

الأخطاء الشائعة وإصلاحها

قفز الاختيار بعد الفرز

لماذا يحدث؟
خُزن موضع المصفوفة بدلا من هوية السجل.
كيف تصلحه؟
خزّن معرّفا مستقرا وحله في البيانات الحالية.
كيف تتجنب تكراره؟
اختبر الإدراج قبل الصف المختار.

تجاهل صف تغير اختيار خارجي

لماذا يحدث؟
أغفل عقد التحديث السطحي الاعتماد الخارجي.
كيف تصلحه؟
استخدم مدخلات لا تُعدّل في مكانها، وأنشئ لقطة جديدة عند تغيرها، مع extraData صريح عند الحاجة.
كيف تتجنب تكراره؟
غيّر الاختيار مع حفظ بيانات العنصر.

اختفاء مسودة خارج الشاشة دون توقع

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

اختبر فهمك

1. لماذا يكون الفهرس مفتاحا غير مناسب لصفوف يمكن إعادة ترتيبها؟

اعرض الحل المشروح

يسمي الفهرس موضعا، وليس سجل مجال. بعد الفرز قد يحوي الموضع نفسه سجلا آخر ويرث حالة محلية خاطئة. استخدم هوية السجل المستقرة، وافحص صفا محررا خلال انتقاله؛ فقد تفوت العناوين المرئية وحدها انتقال الحالة بين السجلات.

2. هل ينبغي استخدام retainVisibleSelection لكل اختيار جماعي متعدد الصفحات؟

اعرض الحل المشروح

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

أهم ما تعلمته

  • موضع الصف ليس هوية السجل
  • اختبر الانتقال والعمر لا التسميات الظاهرة فقط

المراجع الرسمية