الفرق بين المراجعتين لصفحة: «ReactNative/sectionlist»

من موسوعة حسوب
لا ملخص تعديل
لا ملخص تعديل
سطر 1: سطر 1:
= '''SectionList''' =
= SectionList =
وهي واجهة عالية الأداء مستخدمة لإظهار القوائم المقسمة, وتمتاز بما يلي:
وهي واجهة عالية الأداء مستخدمة لإظهار القوائم المقسمة، وتمتاز بما يلي:


* دعم كامل للمنصات المتعددة (cross-platform).
* دعم كامل للمنصات المتعددة (cross-platform).
سطر 12: سطر 12:
* تدعم تحميل التمرير (Scroll loading).
* تدعم تحميل التمرير (Scroll loading).


يمكن استخدام واجهة أبسط مثل <code>[https://reactnative.dev/docs/flatlist FlatList]</code> عند عدم الحاجة لدعم الأقسام.  
يمكن استخدام واجهة أبسط مثل <code>[[ReactNative/flatlist|FlatList]]</code> عند عدم الحاجة لدعم الأقسام.  


== '''مثال''' ==
== مثال ==


* مثال لمكوِّن دالّي (Function Component)
* مثال لمكوِّن دالّي (Function Component)
سطر 166: سطر 166:
export default App;
export default App;


</syntaxhighlight>يعد هذا المكون تغليف ملائمة (convenience wrapper) حول المكون الأساسي <code>[https://reactnative.dev/docs/virtualizedlist VirtualizedList]</code>, لذا فإن خاصياته موروثة منه (كذلك من المكوّن <code>[https://wiki.hsoub.com/ReactNative/scrollview ScrollView]</code>) مع مراعاة ما يلي:
</syntaxhighlight>يعد هذا المكون تغليف ملائمة (convenience wrapper) حول المكون الأساسي <code>[[ReactNative/virtualizedlist|VirtualizedList]]</code>، لذا فإن خاصياته موروثة منه (كذلك من المكوّن <code>[[ReactNative/scrollview|ScrollView]]</code>) مع مراعاة ما يلي:


* إن الحالة الداخلية غير محفوظة عند تمرير المحتوى خارج نافذة الإظهار, لذا يجب التأكد من حفظ البيانات ضمن عنصر البيانات أو في المخازن الخارجية مثل <code>Flux</code> أو <code>Redux</code> أو <code>Relay</code>.
* إن الحالة الداخلية غير محفوظة عند تمرير المحتوى خارج نافذة الإظهار، لذا يجب التأكد من حفظ البيانات ضمن عنصر البيانات أو في المخازن الخارجية مثل <code>Flux</code> أو <code>Redux</code> أو <code>Relay</code>.
* إن هذا المكوّن من النوع الصافي <code>PureComponent</code>, مما يعني أنه لن يتم تحديث الإظهار في حال بقيت قيمة الخاصيات مساوية سطحيًا (shallow-equal) لقيمها السابقة. لذا يجب التأكد من أن كل شيء يتم تمريره كخاصيّة للدالة <code>renderItem</code> لا يحتوي على المساواة السطحية <code>===</code> بعد التحديثات, وإلا فإن الواجهة لن تُحدّث أثناء التغيير. ويتضمن هذا الخاصيّة <code>data</code> ومكوّن الحالة الأب.  
* إن هذا المكوّن من النوع الصافي <code>PureComponent</code>، مما يعني أنه لن يتم تحديث الإظهار في حال بقيت قيمة الخاصيات مساوية سطحيًا (shallow-equal) لقيمها السابقة. لذا يجب التأكد من أن كل شيء يتم تمريره كخاصيّة للدالة <code>renderItem</code> لا يحتوي على المساواة السطحية <code>===</code> بعد التحديثات، وإلا فإن الواجهة لن تُحدّث أثناء التغيير. ويتضمن هذا الخاصيّة <code>data</code> ومكوّن الحالة الأب.
* يظهر المحتوى بشكل غير متزامن خارج نافذة الإظهار, وذلك لتقييد الذاكرة ولتأمين سلاسة في التمرير. مما يعني أنه يمكن التمرير أسرع من معدّل التعبئة (fill rate) مما يؤدي لظهور محتوى فارغ لحظيًا. وهذا عبارة عن مقايضة (tradeoff) يمكن تعديلها لتناسب احتياجات كل تطبيق.  
* يظهر المحتوى بشكل غير متزامن خارج نافذة الإظهار، وذلك لتقييد الذاكرة ولتأمين سلاسة في التمرير. مما يعني أنه يمكن التمرير أسرع من معدّل التعبئة (fill rate) مما يؤدي لظهور محتوى فارغ لحظيًا. وهذا عبارة عن مقايضة (tradeoff) يمكن تعديلها لتناسب احتياجات كل تطبيق.
* تبحث القائمة بشكل افتراضي عن الخاصيّة <code>key</code> ضمن كل عنصر لتستخدمها كمفتاح React, غير أنه يمكن بشكل بديل استخدام الخاصيّة <code>keyExtractor</code> لإدخال مفتاح شخصي.
* تبحث القائمة بشكل افتراضي عن الخاصيّة <code>key</code> ضمن كل عنصر لتستخدمها كمفتاح React، غير أنه يمكن بشكل بديل استخدام الخاصيّة <code>keyExtractor</code> لإدخال مفتاح شخصي.


== '''الخاصيّات (Props)''' ==
== الخاصيّات (Props) ==
موروثة من الخاصيّات <code>[[ReactNative/scrollview|ScrollView]]</code>.
موروثة من الخاصيّات <code>[[ReactNative/scrollview|ScrollView]]</code>.


=== <code>'''renderItem'''</code> ===
=== <code>renderItem</code> ===
المُظهِر الافتراضي لكل عنصر في كل قسم, وهذا المظهر هو عبارة عن دالة تعيد عنصر React.
المُظهِر الافتراضي لكل عنصر في كل قسم، وهذا المظهر هو عبارة عن دالة تعيد عنصر React.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 191: سطر 191:
* <code>section</code> (كائن) - كائن القسم الكامل والمحدد في <code>sections</code>.  
* <code>section</code> (كائن) - كائن القسم الكامل والمحدد في <code>sections</code>.  
* <code>separator</code> (كائن) - كائن له المفاتيح التالية:
* <code>separator</code> (كائن) - كائن له المفاتيح التالية:
** <code>highlight</code> (دالة) - <code>() => void</code>.  
**<code>highlight</code> (دالة) - <code>() => void</code>.
** <code>unhighlight</code> (دالة) - <code>() => void</code>.  
** <code>unhighlight</code> (دالة) - <code>() => void</code>.  
** <code>updateProps</code> (دالة) - <code>(select, newProps) => void</code>.  
** <code>updateProps</code> (دالة) - <code>(select، newProps) => void</code>.  
*** <code>select</code> (قيمة اسمية) - قيمها المحتملة <code>leading</code> أو <code>trailing</code>.
*** <code>select</code> (قيمة اسمية) - قيمها المحتملة <code>leading</code> أو <code>trailing</code>.
*** <code>newProps</code> (كائن).
*** <code>newProps</code> (كائن).


===<code>'''sections'''</code>===
===<code>sections</code>===
تمثّل البيانات الفعلية للإظهار, كما هو الحال مع الخاصيّة <code>data</code> في <code>[https://reactnative.dev/docs/flatlist FlatList]</code>.
تمثّل البيانات الفعلية للإظهار، كما هو الحال مع الخاصيّة <code>data</code> في <code>[[ReactNative/flatlist|FlatList]]</code>.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 207: سطر 207:
|}
|}


===<code>'''extraData'''</code>===
===<code>extraData</code>===
تتضمن البيانات الإضافية التي تحتاجها دوال الإظهار (<code>renderItem</code> والترويسة والتذييل وغيرها) والغير موجودة في <code>data</code>.
تتضمن البيانات الإضافية التي تحتاجها دوال الإظهار (<code>renderItem</code> والترويسة والتذييل وغيرها) والغير موجودة في <code>data</code>.
{| class="wikitable"
{| class="wikitable"
سطر 217: سطر 217:
|}
|}


===<code>'''initialNumToRender'''</code>===
===<code>initialNumToRender</code>===
تحدد عدد العناصر الواجب إظهارها في الدفعة الأولى لتملأ الشاشة لا أكثر.
تحدد عدد العناصر الواجب إظهارها في الدفعة الأولى لتملأ الشاشة لا أكثر.


'''ملاحظة:''' لن يتم استبدال عناصر الإظهار الأولى في الإظهار بالنوافذ (يتم فيه استبدال عناصر نافذة الإظهار الحالية بعناصر النافذة التالية أثناء التمرير وذلك لتحسين الأداء), وذلك للمحافظة على فاعلية التمرير للأعلى.  
'''ملاحظة:''' لن يتم استبدال عناصر الإظهار الأولى في الإظهار بالنوافذ (يتم فيه استبدال عناصر نافذة الإظهار الحالية بعناصر النافذة التالية أثناء التمرير وذلك لتحسين الأداء)، وذلك للمحافظة على فاعلية التمرير للأعلى.  
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 229: سطر 229:
|}
|}


===<code>'''inverted'''</code>===
===<code>inverted</code>===
تعكس اتجاه التمرير باستخدام تحويل مقياس الرسم ذي القيمة <code>1-</code>. 
تعكس اتجاه التمرير باستخدام تحويل مقياس الرسم ذي القيمة <code>1-</code>. 
{| class="wikitable"
{| class="wikitable"
سطر 239: سطر 239:
|}
|}


===<code>'''ItemSeparatorComponent'''</code>===
===<code>ItemSeparatorComponent</code>===
يُظهَر هذا المكوّن بين العناصر ولكن ليس في الأعلى أو الأسفل, ويزوَّد بشكل افتراضي بالخاصيات <code>highlighted</code> و <code>section</code> و <code>[leading/trailing][Item/Section]</code>. كما تتضمن دالة الإظهار <code>renderItem</code> على <code>separators.highlight</code> و <code>separators.unhighlight</code> والمستخدمة لتحديث الخاصيّة <code>highlighted</code>, غير أنه من الممكن إضافة خاصيات شخصية مع <code>separators.</code> <code>updateProps</code>.
يُظهَر هذا المكوّن بين العناصر ولكن ليس في الأعلى أو الأسفل، ويزوَّد بشكل افتراضي بالخاصيات <code>highlighted</code> و <code>section</code> و <code>[leading/trailing][Item/Section]</code>. كما تتضمن دالة الإظهار <code>renderItem</code> على <code>separators.highlight</code> و <code>separators.unhighlight</code> والمستخدمة لتحديث الخاصيّة <code>highlighted</code>، غير أنه من الممكن إضافة خاصيات شخصية مع <code>separators.</code> <code>updateProps</code>.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|عنصر, دالة, مكون (component, function, element)
|عنصر، دالة، مكون (component, function, element)
|لا
|لا
|}
|}


===<code>'''keyExtractor'''</code>===
===<code>keyExtractor</code>===
تُستخدم لاستخراج مفتاح فريد للعنصر المعطى وفق الدليل المحدد, حيث يُستخدم هذا المفتاح من أجل التخزين المؤقت (caching) ومن أجل تعقّب إعادة ترتيب العنصر. يتفحّص المستخرج الافتراضي <code>item.key</code> ثم يعود لاستخدام الدليل, بشكل مماثل لتوثيق React.  
تُستخدم لاستخراج مفتاح فريد للعنصر المعطى وفق الدليل المحدد، حيث يُستخدم هذا المفتاح من أجل التخزين المؤقت (caching) ومن أجل تعقّب إعادة ترتيب العنصر. يتفحّص المستخرج الافتراضي <code>item.key</code> ثم يعود لاستخدام الدليل، بشكل مماثل لتوثيق React.  


'''ملاحظة:''' يضع هذا المستخرج مفتاح لكل عنصر, غير أن كل قسم كامل مازال بحاجة لمفتاحه الخاص.
'''ملاحظة:''' يضع هذا المستخرج مفتاح لكل عنصر، غير أن كل قسم كامل مازال بحاجة لمفتاحه الخاص.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|سلسلة نصية ((item: Item, index: number) => string)
|سلسلة نصية (<code>(item: Item, index: number) => string</code>)
|نعم
|نعم
|}
|}


=== <code>'''ListEmptyComponent'''</code> ===
=== <code>ListEmptyComponent</code> ===
يُظهَر هذا المكوّن عندما تكون القائمة فارغة, ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
يُظهَر هذا المكوّن عندما تكون القائمة فارغة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|عنصر, دالة, مكون (component, function, element)
|عنصر، دالة، مكون (component, function, element)
|لا
|لا
|}
|}


===<code>'''ListFooterComponent'''</code>===
===<code>ListFooterComponent</code>===
يُظهَر هذا المكوّن في آخر القائمة, ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
يُظهَر هذا المكوّن في آخر القائمة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|عنصر, دالة, مكون (component, function, element)
|عنصر، دالة، مكون (component, function, element)
|لا
|لا
|}
|}


===<code>'''ListHeaderComponent'''</code>===
===<code>ListHeaderComponent</code>===
يُظهَر هذا المكوّن في بداية القائمة, ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
يُظهَر هذا المكوّن في بداية القائمة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|عنصر, دالة, مكون (component, function, element)
|عنصر، دالة، مكون (component, function, element)
|لا
|لا
|}
|}


===<code>'''onEndReached'''</code>===
===<code>onEndReached</code>===
تُستدعى عند وصول موقع التمرير إلى العتبة <code>onEndReachedThreshold</code> في المحتوى المُظهَر.
تُستدعى عند وصول موقع التمرير إلى العتبة <code>onEndReachedThreshold</code> في المحتوى المُظهَر.
{| class="wikitable"
{| class="wikitable"
سطر 297: سطر 297:
!مطلوب
!مطلوب
|-
|-
|معلومات ((info: {distanceFromEnd: number}) => void)
|معلومات (<code>(info: {distanceFromEnd: number}) => void</code>)
|لا
|لا
|}
|}


===<code>'''onEndReachedThreshold'''</code>===
===<code>onEndReachedThreshold</code>===
تحدد مسافة أسفل المحتوى المرئي عن أسفل القائمة نسبة إلى طول القسم المرئي من القائمة والتي يجب عندها إطلاق الاستجابة <code>onEndReached</code>, لذا ستُطلق القيمة <code>0.5</code> الاستجابة <code>onEndReached</code> عندما تصبح نهاية المحتوى الظاهر ضمن منتصف الطول المرئي من القائمة.  
تحدد مسافة أسفل المحتوى المرئي عن أسفل القائمة نسبة إلى طول القسم المرئي من القائمة والتي يجب عندها إطلاق الاستجابة <code>onEndReached</code>، لذا ستُطلق القيمة <code>0.5</code> الاستجابة <code>onEndReached</code> عندما تصبح نهاية المحتوى الظاهر ضمن منتصف الطول المرئي من القائمة.  
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 311: سطر 311:
|}
|}


===<code>'''onRefresh'''</code>===
===<code>onRefresh</code>===
تُضيف التحكم بالتحديث المعياري (standard RefreshControl) لوظيفة السحب للتحديث (Pull to Refresh), كما يجب ضبط الخاصيّة <code>refreshing</code> بشكل صحيح. فمثلا توضع القيمة <code>progressViewOffset={100}</code> لجعل إزاحة التحكم بالتحديث 100 نقطة (pt) من أعلى القائمة.
تُضيف التحكم بالتحديث المعياري (standard RefreshControl) لوظيفة السحب للتحديث (Pull to Refresh)، كما يجب ضبط الخاصيّة <code>refreshing</code> بشكل صحيح. فمثلا توضع القيمة <code>progressViewOffset={100}</code> لجعل إزاحة التحكم بالتحديث 100 نقطة (pt) من أعلى القائمة.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|[() => void]
|<code>[() => void]</code>
|لا
|لا
|}
|}


===<code>'''onViewableItemsChanged'''</code>===
===<code>onViewableItemsChanged</code>===
تُستدعى هذه الدالة عند تغيّر قابلية إظهار السطور والمعرّفة بالخاصيّة <code>viewabilityConfig</code>.
تُستدعى هذه الدالة عند تغيّر قابلية إظهار السطور والمعرّفة بالخاصيّة <code>viewabilityConfig</code>.
{| class="wikitable"
{| class="wikitable"
سطر 361: سطر 361:
|لا
|لا
|}
|}
<code>'''refreshing'''</code>
<code>refreshing</code>


تُضبط بالقيمة <code>true</code> لانتظار البيانات الجديدة من أجل التحديث.
تُضبط بالقيمة <code>true</code> لانتظار البيانات الجديدة من أجل التحديث.
سطر 372: سطر 372:
|}
|}


===<code>'''removeClippedSubview'''</code>===
===<code>removeClippedSubview</code>===
تُستخدم لتحسين أداء التمرير في القوائم الطويلة.
تُستخدم لتحسين أداء التمرير في القوائم الطويلة.


'''تنبيه:''' تظهر فيها أحيانًا بعض العيوب مثل المحتوى مفقود, لذا استخدمها على مسؤوليتك الشخصية.
'''تنبيه:''' تظهر فيها أحيانًا بعض العيوب مثل المحتوى مفقود، لذا استخدمها على مسؤوليتك الشخصية.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 384: سطر 384:
|}
|}


===<code>'''renderSectionFooters'''</code>===
===<code>renderSectionFooters</code>===
يُظهَر أسفل كل قسم.
يُظهَر أسفل كل قسم.
{| class="wikitable"
{| class="wikitable"
سطر 390: سطر 390:
!مطلوب
!مطلوب
|-
|-
|عنصر ((info: {section: SectionT}) => ?React.Element<any>)
|عنصر (<code>(info: {section: SectionT}) => ?React.Element<any></code>)
|لا
|لا
|}
|}


===<code>'''renderSectionHeader'''</code>===
===<code>renderSectionHeader</code>===
يُظهَر أعلى كل قسم. كما تلتصق بأعلى عرض التمرير (<code>ScrollView</code>) بشكل افتراضي على منصّة iOS, انظر الخاصيّة <code>stickySectionHeadersEnabled</code>.
يُظهَر أعلى كل قسم. كما تلتصق بأعلى عرض التمرير (<code>ScrollView</code>) بشكل افتراضي على منصّة iOS، انظر الخاصيّة <code>stickySectionHeadersEnabled</code>.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
!مطلوب
!مطلوب
|-
|-
|عنصر ((info: {section: SectionT}) => ?React.Element<any>)
|عنصر (<code>(info: {section: SectionT}) => ?React.Element<any></code>)
|لا
|لا
|}
|}


===<code>'''SectionSeparatorComponent'''</code>===
===<code>SectionSeparatorComponent</code>===
يُظهَر هذا المكوّن في أعلى وأسفل كل قسم (يختلف عن المكوّن <code>ItemSeparatorComponent</code> الذي يُظهَر بين العناصر فقط), ومخصص لفصل الأقسام عن الترويسات التي في الأعلى والأسفل, ولها نفس استجابة الإبراز (highlight) كما هو الحال مع المكوّن <code>ItemSeparatorComponent</code>. كما يستقبل الخاصيات <code>highlighted</code> و <code>[leading/trailing][Item/Section]</code>, وأية خاصيات شخصية من <code>separators.</code> <code>updateProps</code>.
يُظهَر هذا المكوّن في أعلى وأسفل كل قسم (يختلف عن المكوّن <code>ItemSeparatorComponent</code> الذي يُظهَر بين العناصر فقط)، ومخصص لفصل الأقسام عن الترويسات التي في الأعلى والأسفل، ولها نفس استجابة الإبراز (highlight) كما هو الحال مع المكوّن <code>ItemSeparatorComponent</code>. كما يستقبل الخاصيات <code>highlighted</code> و <code>[leading/trailing][Item/Section]</code>، وأية خاصيات شخصية من <code>separators.updateProps</code>.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 414: سطر 414:
|}
|}


===<code>'''stickySectionHeadersEnabled'''</code>===
===<code>stickySectionHeadersEnabled</code>===
تجعل ترويسة القسم تلتصق بأعلى الشاشة حتى تأتي الترويسة التالية وتزيحها, ومفعّلة بشكل افتراضي على منصّة iOS.
تجعل ترويسة القسم تلتصق بأعلى الشاشة حتى تأتي الترويسة التالية وتزيحها، ومفعّلة بشكل افتراضي على منصّة iOS.
{| class="wikitable"
{| class="wikitable"
!النوع
!النوع
سطر 424: سطر 424:
|}
|}


== '''التوابع (Methods)''' ==
== التوابع (Methods) ==


=== <code>'''()scrollToLocation'''</code> ===
=== <code>()scrollToLocation</code> ===
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
scrollToLocation(params);
scrollToLocation(params);
</syntaxhighlight>يمرَّر إلى العنصر المحدد بالخاصيتين <code>sectionIndex</code> و <code>itemIndex</code> (ضمن القسم), والمتوضّع في المنطقة المرئية بناء على الخاصيّة <code>viewPosition</code>, فإذا كانت قيمتها <code>0</code> فإن العنصر يتوضّع في الأعلى وإذا كانت قيمتها <code>1</code> فإنه يتوضّع في الأسفل وإن كانت <code>0.5</code> فإنه يتوضّع في المنتصف.  
</syntaxhighlight>يمرَّر إلى العنصر المحدد بالخاصيتين <code>sectionIndex</code> و <code>itemIndex</code> (ضمن القسم)، والمتوضّع في المنطقة المرئية بناء على الخاصيّة <code>viewPosition</code>، فإذا كانت قيمتها <code>0</code> فإن العنصر يتوضّع في الأعلى وإذا كانت قيمتها <code>1</code> فإنه يتوضّع في الأسفل وإن كانت <code>0.5</code> فإنه يتوضّع في المنتصف.  


'''ملاحظة:''' لا يمكن التمرير لموقع خارج نافذة الإظهار من دون تحديد الخاصيّة <code>getItemLayout</code> أو <code>onScrollToIndexFailed</code>.  
'''ملاحظة:''' لا يمكن التمرير لموقع خارج نافذة الإظهار من دون تحديد الخاصيّة <code>getItemLayout</code> أو <code>onScrollToIndexFailed</code>.  
سطر 445: سطر 445:
مفاتيح الكائن <code>params</code>:
مفاتيح الكائن <code>params</code>:


* <code>animated</code> (قيمة منطقية) - تحدد فيما إذا كانت القائمة ستتحرك أثناء التمرير, وقيمتها الافتراضية <code>true</code>.  
* <code>animated</code> (قيمة منطقية) - تحدد فيما إذا كانت القائمة ستتحرك أثناء التمرير، وقيمتها الافتراضية <code>true</code>.
* <code>itemIndex</code> (عدد) - دليل العنصر الذي سيُمرر إليه داخل القسم. مطلوب.  
* <code>itemIndex</code> (عدد) - دليل العنصر الذي سيُمرر إليه داخل القسم. مطلوب.  
* <code>sectionIndex</code> (عدد) - دليل القسم الذي يحتوي على العنصر الذي سيُمرر إليه. مطلوب.
* <code>sectionIndex</code> (عدد) - دليل القسم الذي يحتوي على العنصر الذي سيُمرر إليه. مطلوب.
سطر 451: سطر 451:
* <code>viewPosition</code> (عدد) - إذا كانت قيمتها <code>0</code> فإن العنصر المطلوب يتوضع في الأعلى وإذا كانت قيمتها <code>1</code> فإنه يتوضّع في الأسفل وإن كانت <code>0.5</code> فإنه يتوضّع في المنتصف.  
* <code>viewPosition</code> (عدد) - إذا كانت قيمتها <code>0</code> فإن العنصر المطلوب يتوضع في الأعلى وإذا كانت قيمتها <code>1</code> فإنه يتوضّع في الأسفل وإن كانت <code>0.5</code> فإنه يتوضّع في المنتصف.  


=== <code>'''()recordInteraction'''</code> ===
=== <code>()recordInteraction</code> ===
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
recordInteraction();
recordInteraction();
</syntaxhighlight>يخبر القائمة بحدوث التفاعل لتقوم بإطلاق حسابات الإظهار, فمثلًا إذا كان المعامل <code>waitForInteractions</code> بالقيمة <code>true</code> فهذا يعني بأن المستخدم لم يمرر بعد. يستدعى هذا التابع عادة عند النقر على العنصر أو عند التنقّل.
</syntaxhighlight>يخبر القائمة بحدوث التفاعل لتقوم بإطلاق حسابات الإظهار، فمثلًا إذا كان المعامل <code>waitForInteractions</code> بالقيمة <code>true</code> فهذا يعني بأن المستخدم لم يمرر بعد. يستدعى هذا التابع عادة عند النقر على العنصر أو عند التنقّل.


=== <code>'''()flashScrollIndicators'''</code> ===
=== <code>()flashScrollIndicators</code> ===
<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
flashScrollIndicators();
flashScrollIndicators();
</syntaxhighlight>يُظهر مؤشرات التمرير لحظيًا, ويعمل على منصًة iOS فقط.
</syntaxhighlight>يُظهر مؤشرات التمرير لحظيًا، ويعمل على منصًة iOS فقط.


== '''تعريفات النوع (Type Definitions)''' ==
== تعريفات النوع (Type Definitions) ==


=== <code>'''Section'''</code> ===
=== <code>'''Section'''</code> ===
سطر 471: سطر 471:
|}
|}


==== '''الخصائص (Properties)''' ====
==== الخصائص (Properties) ====
{| class="wikitable"
{| class="wikitable"
!الاسم
!الاسم
سطر 479: سطر 479:
|<code>data</code>
|<code>data</code>
|مصفوفة (array)
|مصفوفة (array)
|معطيات لإظهار العناصر في القسم, وهي مصفوفة من الكائنات مثل الخاصية   <code>[https://reactnative.dev/docs/flatlist#data FlatList's data prop]</code>
|معطيات لإظهار العناصر في القسم، وهي مصفوفة من الكائنات مثل الخاصية <code>[[ReactNative/flatlist#data|FlatList's data prop]]</code>
|-
|-
|<code>[key]</code>
|<code>[key]</code>
|سلسلة نصية (string)
|سلسلة نصية (string)
|مفتاح اختياري لتعقب إعادة ترتيب الأقسام, ويستخدم دليل الأقسام بشكل افتراضي عند عدم استخدام هذا المفتاح
|مفتاح اختياري لتعقب إعادة ترتيب الأقسام، ويستخدم دليل الأقسام بشكل افتراضي عند عدم استخدام هذا المفتاح
|-
|-
|<code>[renderItem]</code>
|<code>[renderItem]</code>
|عنصر, دالة, مكون (component, function, element)
|عنصر، دالة، مكون (component, function element)
|لتحديد مُظهر اختياري لعناصر القسم بدل المُظهر الافتراضي <code>renderItem</code>
|لتحديد مُظهر اختياري لعناصر القسم بدل المُظهر الافتراضي <code>renderItem</code>
|-
|-
سطر 498: سطر 498:
|}
|}


== '''مصادر''' ==
== مصادر ==


* [https://facebook.github.io/react-native/docs/sectionlist صفحة '''SectionList  '''في توثيق React Native الرسمي.]
* [https://reactnative.dev/docs/sectionlist صفحة SectionList ''' '''في توثيق React Native الرسمي.]

مراجعة 15:48، 18 ديسمبر 2020

SectionList

وهي واجهة عالية الأداء مستخدمة لإظهار القوائم المقسمة، وتمتاز بما يلي:

  • دعم كامل للمنصات المتعددة (cross-platform).
  • تدعم ضبط استجابات الإظهار.
  • تدعم تذييل (footer) القائمة.
  • تدعم فاصل العناصر.
  • تدعم ترويسة القسم.
  • تدعم فاصل الأقسام.
  • تدعم إظهار العناصر والمعطيات الغير متجانسة (Heterogeneous).
  • تدعم السحب للتحديث (Pull to Refresh).
  • تدعم تحميل التمرير (Scroll loading).

يمكن استخدام واجهة أبسط مثل FlatList عند عدم الحاجة لدعم الأقسام.

مثال

  • مثال لمكوِّن دالّي (Function Component)
import React from "react";
import {
  StyleSheet,
  Text,
  View,
  SafeAreaView,
  SectionList
} from "react-native";
import Constants from "expo-constants";

const DATA = [
  {
    title: "Main dishes",
    data: ["Pizza", "Burger", "Risotto"]
  },
  {
    title: "Sides",
    data: ["French Fries", "Onion Rings", "Fried Shrimps"]
  },
  {
    title: "Drinks",
    data: ["Water", "Coke", "Beer"]
  },
  {
    title: "Desserts",
    data: ["Cheese Cake", "Ice Cream"]
  }
];

const Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

const App = () => (
  <SafeAreaView style={styles.container}>
    <SectionList
      sections={DATA}
      keyExtractor={(item, index) => item + index}
      renderItem={({ item }) => <Item title={item} />}
      renderSectionHeader={({ section: { title } }) => (
        <Text style={styles.header}>{title}</Text>
      )}
    />
  </SafeAreaView>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: Constants.statusBarHeight,
    marginHorizontal: 16
  },
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8
  },
  header: {
    fontSize: 32,
    backgroundColor: "#fff"
  },
  title: {
    fontSize: 24
  }
});

export default App;
  • مثال لمكوِّن صنفي (Class Component)
import React, { Component } from "react";
import {
  StyleSheet,
  Text,
  View,
  SafeAreaView,
  SectionList
} from "react-native";
import Constants from "expo-constants";

const DATA = [
  {
    title: "Main dishes",
    data: ["Pizza", "Burger", "Risotto"]
  },
  {
    title: "Sides",
    data: ["French Fries", "Onion Rings", "Fried Shrimps"]
  },
  {
    title: "Drinks",
    data: ["Water", "Coke", "Beer"]
  },
  {
    title: "Desserts",
    data: ["Cheese Cake", "Ice Cream"]
  }
];

Item = ({ title }) => (
  <View style={styles.item}>
    <Text style={styles.title}>{title}</Text>
  </View>
);

class App extends Component {
  render() {
    return (
      <SafeAreaView style={styles.container}>
        <SectionList
          sections={DATA}
          keyExtractor={(item, index) => item + index}
          renderItem={({ item }) => <Item title={item} />}
          renderSectionHeader={({ section: { title } }) => (
            <Text style={styles.header}>{title}</Text>
          )}
        />
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: Constants.statusBarHeight,
    marginHorizontal: 16
  },
  item: {
    backgroundColor: "#f9c2ff",
    padding: 20,
    marginVertical: 8
  },
  header: {
    fontSize: 32,
    backgroundColor: "#fff"
  },
  title: {
    fontSize: 24
  }
});

export default App;

يعد هذا المكون تغليف ملائمة (convenience wrapper) حول المكون الأساسي VirtualizedList، لذا فإن خاصياته موروثة منه (كذلك من المكوّن ScrollView) مع مراعاة ما يلي:

  • إن الحالة الداخلية غير محفوظة عند تمرير المحتوى خارج نافذة الإظهار، لذا يجب التأكد من حفظ البيانات ضمن عنصر البيانات أو في المخازن الخارجية مثل Flux أو Redux أو Relay.
  • إن هذا المكوّن من النوع الصافي PureComponent، مما يعني أنه لن يتم تحديث الإظهار في حال بقيت قيمة الخاصيات مساوية سطحيًا (shallow-equal) لقيمها السابقة. لذا يجب التأكد من أن كل شيء يتم تمريره كخاصيّة للدالة renderItem لا يحتوي على المساواة السطحية === بعد التحديثات، وإلا فإن الواجهة لن تُحدّث أثناء التغيير. ويتضمن هذا الخاصيّة data ومكوّن الحالة الأب.
  • يظهر المحتوى بشكل غير متزامن خارج نافذة الإظهار، وذلك لتقييد الذاكرة ولتأمين سلاسة في التمرير. مما يعني أنه يمكن التمرير أسرع من معدّل التعبئة (fill rate) مما يؤدي لظهور محتوى فارغ لحظيًا. وهذا عبارة عن مقايضة (tradeoff) يمكن تعديلها لتناسب احتياجات كل تطبيق.
  • تبحث القائمة بشكل افتراضي عن الخاصيّة key ضمن كل عنصر لتستخدمها كمفتاح React، غير أنه يمكن بشكل بديل استخدام الخاصيّة keyExtractor لإدخال مفتاح شخصي.

الخاصيّات (Props)

موروثة من الخاصيّات ScrollView.

renderItem

المُظهِر الافتراضي لكل عنصر في كل قسم، وهذا المظهر هو عبارة عن دالة تعيد عنصر React.

النوع مطلوب
كائن (object) لا

يُمرَّر لدالة الإظهار كائن مع المفاتيح التالية:

  • item (كائن) - كائن العنصر والمحدد في data الخاصة بالقسم.
  • index (عدد) - دليل العنصر داخل القسم.
  • section (كائن) - كائن القسم الكامل والمحدد في sections.
  • separator (كائن) - كائن له المفاتيح التالية:
    • highlight (دالة) - () => void.
    • unhighlight (دالة) - () => void.
    • updateProps (دالة) - (select، newProps) => void.
      • select (قيمة اسمية) - قيمها المحتملة leading أو trailing.
      • newProps (كائن).

sections

تمثّل البيانات الفعلية للإظهار، كما هو الحال مع الخاصيّة data في FlatList.

النوع مطلوب
مصفوفة من الأقسام (array of sections) نعم

extraData

تتضمن البيانات الإضافية التي تحتاجها دوال الإظهار (renderItem والترويسة والتذييل وغيرها) والغير موجودة في data.

النوع مطلوب
أي شيء (any) لا

initialNumToRender

تحدد عدد العناصر الواجب إظهارها في الدفعة الأولى لتملأ الشاشة لا أكثر.

ملاحظة: لن يتم استبدال عناصر الإظهار الأولى في الإظهار بالنوافذ (يتم فيه استبدال عناصر نافذة الإظهار الحالية بعناصر النافذة التالية أثناء التمرير وذلك لتحسين الأداء)، وذلك للمحافظة على فاعلية التمرير للأعلى.  

النوع مطلوب
عدد (number) لا

inverted

تعكس اتجاه التمرير باستخدام تحويل مقياس الرسم ذي القيمة 1-

النوع مطلوب
قيمة منطقية (boolean) لا

ItemSeparatorComponent

يُظهَر هذا المكوّن بين العناصر ولكن ليس في الأعلى أو الأسفل، ويزوَّد بشكل افتراضي بالخاصيات highlighted و section و [leading/trailing][Item/Section]. كما تتضمن دالة الإظهار renderItem على separators.highlight و separators.unhighlight والمستخدمة لتحديث الخاصيّة highlighted، غير أنه من الممكن إضافة خاصيات شخصية مع separators. updateProps.

النوع مطلوب
عنصر، دالة، مكون (component, function, element) لا

keyExtractor

تُستخدم لاستخراج مفتاح فريد للعنصر المعطى وفق الدليل المحدد، حيث يُستخدم هذا المفتاح من أجل التخزين المؤقت (caching) ومن أجل تعقّب إعادة ترتيب العنصر. يتفحّص المستخرج الافتراضي item.key ثم يعود لاستخدام الدليل، بشكل مماثل لتوثيق React.

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

النوع مطلوب
سلسلة نصية ((item: Item, index: number) => string) نعم

ListEmptyComponent

يُظهَر هذا المكوّن عندما تكون القائمة فارغة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.

النوع مطلوب
عنصر، دالة، مكون (component, function, element) لا

ListFooterComponent

يُظهَر هذا المكوّن في آخر القائمة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.

النوع مطلوب
عنصر، دالة، مكون (component, function, element) لا

ListHeaderComponent

يُظهَر هذا المكوّن في بداية القائمة، ويمكن أن يكون صنف مكوّن React أو دالة إظهار أو العنصر المُظهَر.

النوع مطلوب
عنصر، دالة، مكون (component, function, element) لا

onEndReached

تُستدعى عند وصول موقع التمرير إلى العتبة onEndReachedThreshold في المحتوى المُظهَر.

النوع مطلوب
معلومات ((info: {distanceFromEnd: number}) => void) لا

onEndReachedThreshold

تحدد مسافة أسفل المحتوى المرئي عن أسفل القائمة نسبة إلى طول القسم المرئي من القائمة والتي يجب عندها إطلاق الاستجابة onEndReached، لذا ستُطلق القيمة 0.5 الاستجابة onEndReached عندما تصبح نهاية المحتوى الظاهر ضمن منتصف الطول المرئي من القائمة.

النوع مطلوب
عدد (number) لا

onRefresh

تُضيف التحكم بالتحديث المعياري (standard RefreshControl) لوظيفة السحب للتحديث (Pull to Refresh)، كما يجب ضبط الخاصيّة refreshing بشكل صحيح. فمثلا توضع القيمة progressViewOffset={100} لجعل إزاحة التحكم بالتحديث 100 نقطة (pt) من أعلى القائمة.

النوع مطلوب
[() => void] لا

onViewableItemsChanged

تُستدعى هذه الدالة عند تغيّر قابلية إظهار السطور والمعرّفة بالخاصيّة viewabilityConfig.

النوع مطلوب
دالة (function) لا

يُمرر لهذه الدالة كائن له المفاتيح التالية:

  • viewableItems (مصفوفة من ViewToken)
  • changed (مصفوفة من ViewToken)

يُصدَّر النوع ViewToken عن طريق ViewabilityHelper.js:

الاسم النوع مطلوب
item أي نوع (any) نعم
key سلسلة نصية (string) نعم
index عدد (number) لا
isViewable قيمة منطقية (boolean) نعم
section أي نوع (any) لا

refreshing

تُضبط بالقيمة true لانتظار البيانات الجديدة من أجل التحديث.

النوع مطلوب
قيمة منطقية (bool) لا

removeClippedSubview

تُستخدم لتحسين أداء التمرير في القوائم الطويلة.

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

النوع مطلوب
قيمة منطقية (bool) لا

renderSectionFooters

يُظهَر أسفل كل قسم.

النوع مطلوب
عنصر ((info: {section: SectionT}) => ?React.Element<any>) لا

renderSectionHeader

يُظهَر أعلى كل قسم. كما تلتصق بأعلى عرض التمرير (ScrollView) بشكل افتراضي على منصّة iOS، انظر الخاصيّة stickySectionHeadersEnabled.

النوع مطلوب
عنصر ((info: {section: SectionT}) => ?React.Element<any>) لا

SectionSeparatorComponent

يُظهَر هذا المكوّن في أعلى وأسفل كل قسم (يختلف عن المكوّن ItemSeparatorComponent الذي يُظهَر بين العناصر فقط)، ومخصص لفصل الأقسام عن الترويسات التي في الأعلى والأسفل، ولها نفس استجابة الإبراز (highlight) كما هو الحال مع المكوّن ItemSeparatorComponent. كما يستقبل الخاصيات highlighted و [leading/trailing][Item/Section]، وأية خاصيات شخصية من separators.updateProps.

النوع مطلوب
صنف React لا

stickySectionHeadersEnabled

تجعل ترويسة القسم تلتصق بأعلى الشاشة حتى تأتي الترويسة التالية وتزيحها، ومفعّلة بشكل افتراضي على منصّة iOS.

النوع مطلوب
قيمة منطقية (bool) لا

التوابع (Methods)

()scrollToLocation

scrollToLocation(params);

يمرَّر إلى العنصر المحدد بالخاصيتين sectionIndex و itemIndex (ضمن القسم)، والمتوضّع في المنطقة المرئية بناء على الخاصيّة viewPosition، فإذا كانت قيمتها 0 فإن العنصر يتوضّع في الأعلى وإذا كانت قيمتها 1 فإنه يتوضّع في الأسفل وإن كانت 0.5 فإنه يتوضّع في المنتصف.  

ملاحظة: لا يمكن التمرير لموقع خارج نافذة الإظهار من دون تحديد الخاصيّة getItemLayout أو onScrollToIndexFailed.

الاسم النوع مطلوب الوصف
params كائن (object) نعم انظر في الأسفل

مفاتيح الكائن params:

  • animated (قيمة منطقية) - تحدد فيما إذا كانت القائمة ستتحرك أثناء التمرير، وقيمتها الافتراضية true.
  • itemIndex (عدد) - دليل العنصر الذي سيُمرر إليه داخل القسم. مطلوب.
  • sectionIndex (عدد) - دليل القسم الذي يحتوي على العنصر الذي سيُمرر إليه. مطلوب.
  • viewOffset (عدد) - عدد ثابت من البكسلات لتحديد إزاحة عن الموقع المطلوب.
  • viewPosition (عدد) - إذا كانت قيمتها 0 فإن العنصر المطلوب يتوضع في الأعلى وإذا كانت قيمتها 1 فإنه يتوضّع في الأسفل وإن كانت 0.5 فإنه يتوضّع في المنتصف.

()recordInteraction

recordInteraction();

يخبر القائمة بحدوث التفاعل لتقوم بإطلاق حسابات الإظهار، فمثلًا إذا كان المعامل waitForInteractions بالقيمة true فهذا يعني بأن المستخدم لم يمرر بعد. يستدعى هذا التابع عادة عند النقر على العنصر أو عند التنقّل.

()flashScrollIndicators

flashScrollIndicators();

يُظهر مؤشرات التمرير لحظيًا، ويعمل على منصًة iOS فقط.

تعريفات النوع (Type Definitions)

Section

كائن معرّف للمعطيات التي ستُظهَر في القسم.

النوع
أي نوع (any)

الخصائص (Properties)

الاسم النوع الوصف
data مصفوفة (array) معطيات لإظهار العناصر في القسم، وهي مصفوفة من الكائنات مثل الخاصية FlatList's data prop
[key] سلسلة نصية (string) مفتاح اختياري لتعقب إعادة ترتيب الأقسام، ويستخدم دليل الأقسام بشكل افتراضي عند عدم استخدام هذا المفتاح
[renderItem] عنصر، دالة، مكون (component, function element) لتحديد مُظهر اختياري لعناصر القسم بدل المُظهر الافتراضي renderItem
[ItemSeparatorComponent] قيمة منطقية (boolean) لتحديد فاصل اختياري لعناصر القسم بدل الفاصل الافتراضي ItemSeparatorComponent
[keyExtractor] دالة (function) لتحديد مستخرج مفتاح اختياري للقسم بدل المستخرج الافتراضي keyExtractor

مصادر