اللمس والأزرار Pressable والقوائم FlatList
التفاعل باللمس وعرض القوائم بكفاءة. ⏱ نحو 40 دقيقة.
- تستقبل اللمس بـ
Pressableوتستجيب لحالة الضغط. - تعرف لماذا
FlatListأفضل منmapللقوائم الطويلة. - تعرض قائمةً بـ
dataوrenderItemوkeyExtractor.
١اللمس: Pressable
على الهاتف نتفاعل باللمس لا بالنقر. Pressable منطقةٌ تستقبل اللمس عبر onPress، وتعرف إن كان الإصبع فوقها عبر دالةٍ تتلقّى { pressed }:
import { useState } from 'react';import { View, Text, Pressable, StyleSheet } from 'react-native'; export default function App() { const [likes, setLikes] = useState(0); return ( <View style={{ padding: 24, alignItems: 'center' }}> <Text style={styles.n}>❤️ {likes}</Text> <Pressable onPress={() => setLikes(likes + 1)} style={({ pressed }) => [styles.btn, pressed && styles.pressed]} > <Text style={styles.t}>أعجبني</Text> </Pressable> </View> );} const styles = StyleSheet.create({ n: { fontSize: 32, fontWeight: 'bold', marginBottom: 14 }, btn: { backgroundColor: '#E8820C', paddingVertical: 12, paddingHorizontal: 22, borderRadius: 12 }, pressed: { opacity: 0.6 }, t: { color: 'white', fontSize: 16 },});
لاحظ أن style يمكن أن تكون دالةً تستقبل حالة اللمس — فنغيّر المظهر أثناء الضغط.
٢القوائم الطويلة: لماذا FlatList؟
لعرض قائمةٍ قد تطول (مئات العناصر)، لا نرسمها كلها دفعةً واحدة — يستهلك ذاكرة الجهاز. FlatList يرسم المرئيّ فقط ويعيد تدوير العناصر عند التمرير (أساسٌ للأداء، وحدة 11):
map يدويًّا | FlatList | |
|---|---|---|
| يرسم | كل العناصر دفعة | المرئيّ فقط |
| ذاكرة | تكبر مع العدد | ثابتة تقريبًا |
| مناسب لـ | قائمة قصيرة | قائمة طويلة/غير محدودة |
٣FlatList: data و renderItem و keyExtractor
ثلاث خصائص أساسية: data المصفوفة، وrenderItem دالةٌ ترسم كل عنصر، وkeyExtractor يعطي كلّ عنصرٍ مفتاحًا فريدًا:
import { View, Text, FlatList, StyleSheet } from 'react-native'; const PRODUCTS = [ { id: 'p1', name: 'قهوة', price: 18 }, { id: 'p2', name: 'شاي', price: 12 }, { id: 'p3', name: 'عصير', price: 15 },]; export default function App() { return ( <FlatList style={{ padding: 10 }} data={PRODUCTS} keyExtractor={(item) => item.id} renderItem={({ item }) => ( <View style={styles.row}> <Text style={styles.name}>{item.name}</Text> <Text style={styles.price}>{item.price} ر.س</Text> </View> )} /> );} const styles = StyleSheet.create({ row: { flexDirection: 'row', justifyContent: 'space-between', padding: 12, borderBottomWidth: 1, borderColor: '#eee' }, name: { fontSize: 16 }, price: { fontWeight: 'bold', color: '#E8820C' },});
renderItem يستقبل كائنًا فيه item (العنصر الحالي). keyExtractor يمنع تحذير المفاتيح ويسرّع التحديث.
توقّع وتحقّق
ما الذي يستقبل اللمس في React Native؟
لماذا نفضّل FlatList على map لقائمةٍ طويلة؟
أي خاصية ترسم كل عنصر في FlatList؟
دور keyExtractor:
الخلاصة
Pressableيستقبل اللمس عبرonPress، وstyleقد تكون دالةً تقرأpressed.FlatListيرسم المرئيّ فقط فيوفّر ذاكرة الجهاز.FlatListيحتاجdataوrenderItemوkeyExtractor(مفتاح فريد).
تحدٍّ برمجي: قائمة مهامّ
متوسطاعرض قائمة مهامّ بـ FlatList، وزرًّا يزيد عدّاد المنجَز.
- عرّف مصفوفة مهامّ (3 عناصر على الأقل) لكلٍّ
idوtitle. - اعرضها بـ
FlatListمعkeyExtractor، وكل عنوانٍ في<Text>. - أضف
<Text testID="count">يعرض عدد المهامّ.
👀 اعرض الناتج المطلوب (وجرّبه)
- الكود يعمل بلا أخطاء في Console
- العدّاد يعرض 3
- تظهر ثلاث مهامّ على الأقل
- استُخدم FlatList
- استُخدم keyExtractor
💡 تلميح 1
💡 تلميح 2
TASKS.length.حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import { View, Text, FlatList, StyleSheet } from 'react-native'; const TASKS = [ { id: 't1', title: 'مراجعة الدرس' }, { id: 't2', title: 'حلّ التحدي' }, { id: 't3', title: 'تسليم المشروع' },]; export default function App() { return ( <View style={{ padding: 10 }}> <Text testID="count" style={styles.count}>عدد المهامّ: {TASKS.length}</Text> <FlatList data={TASKS} keyExtractor={(item) => item.id} renderItem={({ item }) => <Text style={styles.row}>• {item.title}</Text>} /> </View> );} const styles = StyleSheet.create({ count: { fontWeight: 'bold', marginBottom: 8, color: '#E8820C' }, row: { padding: 8, fontSize: 15 },});