طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 251 · برمجة الأجهزة الذكية
الدرس 5 · الوحدة 2: تطوير واجهات المستخدم للأجهزة الذكية

الإدخال TextInput والحالة useState

استقبال إدخال المستخدم وربطه بالحالة. ⏱ نحو 35 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تستقبل إدخال المستخدم بـ TextInput و onChangeText.
  • تبني حقلًا متحكَّمًا به تكون الحالة مصدر قيمته.
  • تعالج المُدخَل أثناء الكتابة (حساب، تحقّق، إضافة لقائمة).

١استقبال إدخال المستخدم

TextInput حقلُ إدخالٍ على الجهاز. بخلاف الويب، حدث التغيير اسمه onChangeText ويعطيك النصّ مباشرةً (لا كائن حدث). ونربط قيمته بحالةٍ عبر value — هذا «الحقل المتحكَّم به»:

import { useState } from 'react';import { View, Text, TextInput, StyleSheet } from 'react-native'; export default function App() {  const [name, setName] = useState('');  return (    <View style={{ padding: 20 }}>      <TextInput        style={styles.input}        placeholder="اكتب اسمك"        value={name}        onChangeText={setName}      />      <Text style={styles.greet}>        {name ? 'مرحبًا يا ' + name + ' 👋' : 'الحقل فارغ'}      </Text>    </View>  );} const styles = StyleSheet.create({  input: { borderWidth: 1, borderColor: '#E8820C', borderRadius: 10, padding: 10, fontSize: 16 },  greet: { marginTop: 12, fontSize: 18 },});

القيمة والحالة مرتبطتان: ما تكتبه يُحدِّث name، وname يُحدِّث العرض فورًا.

٢الحقل المتحكَّم به

«متحكَّمٌ به» يعني أن الحالة هي مصدر الحقيقة: الحقل يعرض value، وكل ضغطةٍ تحدّث الحالة التي تعيد عرض الحقل. فائدته: تستطيع التحقّق أو التعديل أثناء الكتابة.

import { useState } from 'react';import { View, Text, TextInput, StyleSheet } from 'react-native'; export default function App() {  const [price, setPrice] = useState('');  const num = Number(price) || 0;  const withVat = (num * 1.15).toFixed(2);  return (    <View style={{ padding: 20 }}>      <TextInput        style={styles.input}        placeholder="السعر قبل الضريبة"        keyboardType="numeric"        value={price}        onChangeText={setPrice}      />      <Text style={styles.out}>السعر مع الضريبة (15%): {withVat} ر.س</Text>    </View>  );} const styles = StyleSheet.create({  input: { borderWidth: 1, borderColor: '#ccc', borderRadius: 10, padding: 10 },  out: { marginTop: 12, fontSize: 16, fontWeight: 'bold', color: '#2E7D32' },});

keyboardType="numeric" يطلب لوحة أرقامٍ على الجهاز. نحسب الضريبة أثناء الكتابة لأن الحقل متحكَّمٌ به.

٣نموذجٌ صغير

نجمع حقلًا وزرًّا: عند اللمس نضيف المُدخَل إلى قائمة:

import { useState } from 'react';import { View, Text, TextInput, Pressable, StyleSheet } from 'react-native'; export default function App() {  const [text, setText] = useState('');  const [items, setItems] = useState([]);  function add() {    if (!text.trim()) return;    setItems([...items, text.trim()]);    setText('');  }  return (    <View style={{ padding: 16 }}>      <View style={{ flexDirection: 'row', gap: 8 }}>        <TextInput style={styles.input} placeholder="عنصر جديد" value={text} onChangeText={setText} />        <Pressable style={styles.btn} onPress={add}><Text style={styles.bt}>إضافة</Text></Pressable>      </View>      {items.map((it, i) => <Text key={i} style={styles.row}>• {it}</Text>)}    </View>  );} const styles = StyleSheet.create({  input: { flex: 1, borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 8 },  btn: { backgroundColor: '#E8820C', borderRadius: 8, justifyContent: 'center', paddingHorizontal: 14 },  bt: { color: 'white' },  row: { paddingVertical: 6, fontSize: 15 },});

توقّع وتحقّق

حدث تغيّر النصّ في TextInput:

ماذا يعطيك onChangeText؟

«الحقل المتحكَّم به» يعني:

لطلب لوحة أرقام:

الخلاصة

تحدٍّ برمجي: عدّاد أحرف

متوسط

حقلٌ متحكَّمٌ به يعرض عدد الأحرف المكتوبة حيًّا.

المطلوب:
  • حالة نصّية بـ useState.
  • TextInput متحكَّمٌ به: value وonChangeText.
  • <Text testID="len"> يعرض طول النصّ (text.length).
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء في Console
  • العدّاد يبدأ من 0
  • الحقل متحكَّمٌ به (value)
  • استُخدم onChangeText
  • عُرض text.length

💡 تلميح 1
اربط value={text} و onChangeText={setText}.
💡 تلميح 2
العدّاد: {text.length}.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

import { useState } from 'react';import { View, Text, TextInput, StyleSheet } from 'react-native'; export default function App() {  const [text, setText] = useState('');  return (    <View style={{ padding: 20 }}>      <TextInput style={styles.input} placeholder="اكتب هنا" value={text} onChangeText={setText} />      <Text testID="len" style={styles.len}>عدد الأحرف: {text.length}</Text>    </View>  );} const styles = StyleSheet.create({  input: { borderWidth: 1, borderColor: '#E8820C', borderRadius: 10, padding: 10 },  len: { marginTop: 10, fontWeight: 'bold', color: '#E8820C' },});
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس