لماذا تطبيقات الأجهزة الذكية؟ أول شاشة React Native
من واجهات الويب إلى تطبيقٍ في يدك يتفاعل مع مستشعراته. ⏱ نحو 35 دقيقة.
- تشرح ما تطبيقات الأجهزة الذكية وكيف تختلف عن الويب.
- تكتب أول شاشة
React NativeبـViewوTextوStyleSheet. - تضيف تفاعلًا باللمس والحالة، وتقرأ مستشعرًا بسيطًا.
- تقارن
React NativeبـFlutterوتعرف لماذا نبدأ بالأول.
١من الويب إلى الجهاز في يدك
في مقرر 242 بنيت واجهات ويب بـ React تعمل في المتصفّح. الآن ننقل المهارة نفسها إلى الهاتف الذكي: تطبيقٌ يُثبَّت على الجهاز، يتفاعل مع مستشعراته (الإمالة، الضوء، الموقع، الكاميرا)، ويعمل على Android و iOS من كودٍ واحد.
الأداة التي نستخدمها React Native: تكتب مكوّنات بالفكرة نفسها (JSX، حالة، خصائص)، لكن بدل <div> و<p> تستخدم مكوّناتٍ أصيلة: <View> و<Text>. يحوّلها الإطار إلى عناصر واجهة أصيلة حقيقية على الجهاز.
تطبيق ويب (242) | تطبيق جهاز ذكيّ (251) | |
|---|---|---|
| يعمل في | المتصفّح | الهاتف (Android/iOS) |
| لبنة الواجهة | <div> <p> <button> | <View> <Text> <Pressable> |
| المستشعرات | محدودة | إمالة، ضوء، موقع، كاميرا |
| الأداة | React + Vite | React Native (أو Flutter) |
٢أول شاشة: View و Text
المكوّن في React Native دالةٌ تعيد JSX، لكن بمكوّنات الجهاز. View حاوية (مثل div)، وText لكل نصّ (لا يمكن كتابة نصّ خارج Text). جرّب — المعاينة تعمل فعلًا داخل الهاتف:
import { View, Text } from 'react-native'; export default function App() { return ( <View style={{ padding: 20 }}> <Text style={{ fontSize: 22, fontWeight: 'bold' }}>مرحبًا بالأجهزة الذكية 📱</Text> <Text style={{ marginTop: 8, color: '#555' }}> هذا أول تطبيق React Native تكتبه. </Text> </View> );}
٣الأنماط: StyleSheet
بدل CSS، تُكتب الأنماط كائناتٍ JavaScript. نجمعها بـ StyleSheet.create لتنظيمها وتحسين الأداء. الأسماء بأسلوب camelCase (backgroundColor لا background-color)، والأرقام تعني وحداتٍ مستقلة عن الكثافة (لا بكسل):
import { View, Text, StyleSheet } from 'react-native'; export default function App() { return ( <View style={styles.card}> <Text style={styles.title}>بطاقة منتج</Text> <Text style={styles.price}>٤٩٩ ريال</Text> </View> );} const styles = StyleSheet.create({ card: { backgroundColor: '#E8820C', padding: 16, borderRadius: 14, margin: 10 }, title: { color: 'white', fontSize: 20, fontWeight: 'bold' }, price: { color: '#FFE8CC', fontSize: 16, marginTop: 6 },});
٤تفاعل حيّ: اللمس والحالة
Pressable يستقبل اللمس، وuseState يحفظ الحالة — كما في React تمامًا. اضغط الزرّ في الهاتف:
import { useState } from 'react';import { View, Text, Pressable, StyleSheet } from 'react-native'; export default function App() { const [count, setCount] = useState(0); return ( <View style={styles.box}> <Text style={styles.n}>{count}</Text> <Pressable style={styles.btn} onPress={() => setCount(count + 1)}> <Text style={styles.bt}>اضغط لزيادة العدّاد</Text> </Pressable> </View> );} const styles = StyleSheet.create({ box: { alignItems: 'center', padding: 24 }, n: { fontSize: 48, fontWeight: 'bold', color: '#E8820C' }, btn: { backgroundColor: '#E8820C', paddingVertical: 12, paddingHorizontal: 18, borderRadius: 12, marginTop: 14 }, bt: { color: 'white', fontSize: 16 },});
٥لمحة: قراءة مستشعر
ما يميّز الأجهزة الذكية هو المستشعرات. سنتعمّق فيها لاحقًا، لكن إليك لمحة: نقرأ البطارية من محاكي SmartDevice ونعرضها. حرّك منزلق البطارية في لوحة المستشعرات أسفل الهاتف ولاحظ تحدّث الرقم واللون حيًّا:
import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() { const bat = useBattery(); // {level, saver} const low = bat.level < 20; return ( <View style={styles.box}> <Text style={styles.lbl}>حالة البطارية</Text> <Text style={[styles.pct, { color: low ? '#C62828' : '#2E7D32' }]}> {bat.level}% </Text> <Text style={styles.hint}> {low ? '🔴 بطارية منخفضة!' : '🟢 جيدة'}{bat.saver ? ' · وضع التوفير' : ''} </Text> </View> );} const styles = StyleSheet.create({ box: { alignItems: 'center', padding: 24 }, lbl: { fontSize: 15, color: '#666' }, pct: { fontSize: 44, fontWeight: 'bold', marginVertical: 6 }, hint: { fontSize: 15 },});
هذا هو جوهر المقرر: كودك يستمع للمستشعر، والواجهة تستجيب. لاحظ أن القيمة تبدأ من 80% ثم تتبعك.
٦المنصّات: React Native و Flutter
تذكر الخطة أداتين لتطوير تطبيقٍ واحد يعمل على عدّة منصّات:
| React Native | Flutter | |
|---|---|---|
| اللغة | JavaScript / JSX | Dart |
| من | Meta | |
| الفكرة | مكوّنات تتحوّل لعناصر أصيلة | Widgets تُرسَم على لوحة خاصة |
| نستخدمه هنا | نكتبه ونشغّله | نعرض كودَه ونشرحه (الوحدة 6) |
نركّز على React Native لأنه امتداد مباشر لـ React الذي أتقنته، ونخصّص الوحدة السادسة لفهم Flutter ومقارنته. كلاهما يحقّق الهدف: كودٌ واحد، منصّتان.
توقّع وتحقّق
ما المكوّن الذي يقابل <div> في React Native؟
View حاوية عامة.أين يجب أن يوضع كل نصّ؟
Text خطأ.كيف تُكتب الأنماط في React Native؟
StyleSheet.create.لماذا نختار React Native امتدادًا لمهارتك؟
JSX وحالة وخصائص.الخلاصة
React Nativeينقل مهارةReactإلى الهاتف:Viewبدلdiv، وTextلكل نصّ.- الأنماط كائنات
JavaScriptتُجمع بـStyleSheet.createبأسماءcamelCase. Pressable + useStateيصنعان التفاعل، تمامًا كما فيReact.- المستشعرات جوهر المقرر: كودك يستمع، والواجهة تستجيب — نجرّبها في هاتفٍ محاكى بلوحة مستشعرات.
- كودٌ واحد يعمل على منصّتين؛ نبدأ بـ
React NativeونفهمFlutterفي الوحدة 6.
تحدٍّ برمجي: شاشة تعريف بتطبيق
سهلاصنع شاشة ترحيبٍ بسيطة بمكوّنات React Native.
- استورد
ViewوTextمنreact-native. - أضف
<Text testID="title">نصّه «تطبيقي الذكي». - أضف
<Text testID="sub">نصّه «أول تطبيق أجهزة ذكية». - ضعهما داخل
<View>واحدة، وصدّر App افتراضيًّا.
👀 اعرض الناتج المطلوب (وجرّبه)
- الكود يعمل بلا أخطاء في Console
- العنوان في
testID=title - العنوان الفرعي في
testID=sub - استُخدم مكوّن Text مرتين
💡 تلميح 1
<Text testID="…">النص</Text>.💡 تلميح 2
data-testid في المعاينة.حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import { View, Text } from 'react-native'; export default function App() { return ( <View style={{ padding: 20 }}> <Text testID="title" style={{ fontSize: 22, fontWeight: 'bold' }}>تطبيقي الذكي</Text> <Text testID="sub" style={{ color: '#555', marginTop: 6 }}>أول تطبيق أجهزة ذكية</Text> </View> );}