التفاعل مع مكوّنات الجهاز: مقدمة المستشعرات
بوّابة المقرر: الجهاز يستشعر العالم، وتطبيقك يستجيب. ⏱ نحو 40 دقيقة.
- تعدّد مستشعرات الجهاز الذكيّ واستخداماتها.
- تفهم أن المستشعر مصدرٌ متدفّق نشترك فيه.
- تقرأ مستشعرًا حيًّا بخطّاف وباشتراكٍ يدويّ.
- تعرف دور دالّة الإلغاء في منع تسرّب الذاكرة.
١ما الذي يميّز الجهاز الذكيّ؟
الفرق الجوهريّ بين تطبيق الهاتف وصفحة الويب هو المستشعرات: أجهزةٌ صغيرة تقيس العالم حول الجهاز وتُغذّي تطبيقك ببياناتٍ حيّة.
| المستشعر | يقيس | استخدامٌ نموذجيّ |
|---|---|---|
| التسارع/الإمالة | ميل الجهاز وحركته | ألعاب، مستوى، عدّ خطوات |
| الضوء | سطوع المحيط | سطوع تلقائيّ، وضع ليليّ |
| الموقع GPS | خطّ العرض والطول | خرائط، توصيل، طقس |
| الكاميرا | الصور والفيديو | مسح، تصوير، QR |
| البطارية | الشحن ووضع التوفير | ترشيد الأداء |
٢نمط القراءة: اشترك فيُحدّثك
المستشعر مصدرٌ متدفّق: لا تسأله مرّةً، بل تشترك فيه فيُنادي دالّتك كلّما تغيّرت القيمة. في React نربط ذلك بالحالة عبر useEffect — أو نستخدم خطّافًا جاهزًا يفعل ذلك عنّا:
| الطريقة | كيف | متى |
|---|---|---|
SmartDevice.useBattery() | خطّافٌ يعيد القيمة الحيّة | الأسهل داخل مكوّن |
SmartDevice.onBattery(cb) | اشتراكٌ يدويّ يعيد دالّة إلغاء | خارج React أو لتحكّمٍ دقيق |
SmartDevice.get("battery") | قراءةٌ لحظيّة واحدة | قيمةٌ آنيّة بلا متابعة |
٣أول مستشعر حيّ: البطارية
نقرأ البطارية بخطّاف useBattery. حرّك منزلق البطارية وزرّ التوفير في لوحة المستشعرات وراقب الاستجابة:
import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() { const bat = useBattery(); const color = bat.level < 20 ? '#C62828' : bat.level < 50 ? '#E8820C' : '#2E7D32'; return ( <View style={styles.box}> <Text testID="pct" style={[styles.pct, { color }]}>{bat.level}%</Text> <View style={styles.barBg}> <View style={[styles.barFill, { width: bat.level + '%', backgroundColor: color }]} /> </View> <Text style={styles.note}>{bat.saver ? '🔋 وضع التوفير مفعّل' : 'وضع عاديّ'}</Text> </View> );} const styles = StyleSheet.create({ box: { padding: 24, alignItems: 'center' }, pct: { fontSize: 44, fontWeight: 'bold' }, barBg: { width: 180, height: 14, backgroundColor: '#eee', borderRadius: 7, marginTop: 10, overflow: 'hidden' }, barFill: { height: 14 }, note: { marginTop: 10, fontSize: 15 },});
شريط التعبئة عرضه = مستوى البطارية. منطقك (اللون، النصّ) يستجيب لكل حركة.
٤اشتراكٌ يدويّ خارج الخطّاف
أحيانًا تحتاج الاشتراك يدويًّا. onBattery يستقبل دالّةً تُنادى بالقيمة، ويعيد دالّة إلغاء نستدعيها في تنظيف useEffect (سنتعمّق في دورة الحياة في الدرس 15):
import { useState, useEffect } from 'react';import SmartDevice from 'smartdevice'; function useLowBattery() { const [low, setLow] = useState(false); useEffect(() => { const stop = SmartDevice.onBattery((b) => setLow(b.level < 20)); return stop; // إلغاء الاشتراك عند إزالة المكوّن }, []); return low;}
الاشتراك يُنشأ مرة (مصفوفة اعتماديّات فارغة)، ودالّة الإلغاء تمنع تسرّب الذاكرة. هذا هو النمط الذي تبنى عليه كل قراءات المستشعرات.
توقّع وتحقّق
ما الذي يميّز الجهاز الذكيّ عن صفحة الويب؟
المستشعر مصدرٌ:
أسهل طريقةٍ لقراءة مستشعرٍ داخل مكوّن:
دالّة الإلغاء التي يعيدها الاشتراك تُستخدم لـ:
الخلاصة
- المستشعرات ما يميّز تطبيق الجهاز: إمالة، ضوء، موقع، كاميرا، بطارية.
- المستشعر متدفّق: نشترك فيه فيُحدّثنا، ونربطه بالحالة.
- الخطّاف
(useBattery)أسهل؛ والاشتراك اليدويّ(onBattery)يعيد دالّة إلغاء. - دالّة الإلغاء تمنع تسرّب الذاكرة عند إزالة المكوّن.
تحدٍّ برمجي: تنبيه بطارية
متوسطاقرأ البطارية واعرض تنبيهًا يتغيّر مع المستوى.
- استورد
useBatteryمنsmartdevice. - اعرض
<Text testID="level">فيه المستوى %. - اعرض
<Text testID="msg">: إن كان أقل من 20 «اشحن الآن» وإلا «البطارية جيدة».
👀 اعرض الناتج المطلوب (وجرّبه)
- الكود يعمل بلا أخطاء في Console
- المستوى الابتدائيّ 80%
- الرسالة الابتدائيّة «البطارية جيدة»
- استُخدم useBattery
💡 تلميح 1
💡 تلميح 2
bat.level < 20.حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() { const bat = useBattery(); const low = bat.level < 20; return ( <View style={{ padding: 20 }}> <Text testID="level" style={styles.lvl}>{bat.level}%</Text> <Text testID="msg" style={{ color: low ? '#C62828' : '#2E7D32' }}> {low ? 'اشحن الآن' : 'البطارية جيدة'} </Text> </View> );} const styles = StyleSheet.create({ lvl: { fontSize: 36, fontWeight: 'bold', color: '#E8820C' },});