نوفيل
الرئيسيةالكورساتالتحديات⚔️ المبارزاتالمقالاتالأدواتتغريداتالمجتمع
دخولابدأ مجاناً
نوفيل

منصة تعليم البرمجة الأولى بالعربي. تعلم من الصفر حتى الاحتراف مع كورسات احترافية وتحديات ذكاء اصطناعي.

المنصة

  • الكورسات
  • التحديات
  • المقالات
  • الأدوات

الحساب

  • إنشاء حساب
  • تسجيل الدخول
  • لوحة التحكم
  • الملف الشخصي

روابط

  • سياسة الخصوصية
  • شروط الاستخدام
  • عن نوفيل
  • تواصل معنا

© 2026 نوفيل. جميع الحقوق محفوظة.

صُنع بـ في مصر

نوفيل
الرئيسيةالكورساتالتحديات⚔️ المبارزاتالمقالاتالأدواتتغريداتالمجتمع
دخولابدأ مجاناً
REA

منهج React Js

دليل مرجعي شامل

كل اللغات
مدرسة البرمجة/منهج React Js/جلب البيانات من السيرفر

جلب البيانات من السيرفر

جلب البيانات في ريأكتData Fetching Reactالتعامل مع API في useState و useEffectحالة التحميل Loading Stateإدار الأخطاءإدار الأخطاء في react js

جدول مرجعي سريع

1

جلب البيانات من السيرفر (Data Fetching) وإدارة حالات التحميل والخطأ

الحالة البرمجيةدورها في دورة حياة المكونالأثر المباشر على واجهة المستخدم (UX)
Data Stateتخزين الاستجابة الناجحة القادمة من السيرفر (API Response)عرض قائمة الكورسات أو المحتوى التفاعلي فور اكتمال وصوله
Loading Stateمؤشر بولياني (Boolean) يحدد ما إذا كان الطلب جارياً في الخلفيةعرض مؤشر تحميل (Spinner/Skeleton) لمنع ارتباك المستخدم أو التفاعل المسبق
Error Stateتخزين رسالة الخطأ في حال فشل الاتصال أو إرجاع السيرفر لكود خطأإظهار تنبيه أو زر إعادة المحاولة (Retry) بدلاً من انهيار التطبيق
Abort Signalآلية لإيقاف طلب الـ HTTP الملغى عند خروج المستخدم من الصفحةمنع تسريب الذاكرة وتحديث حالة مكون غير موجود في الشاشة

الشرح

جلب البيانات عبر الشبكة (Async Data Fetching) هو أحد أبرز التأثيرات الجانبية (Side Effects) في تطبيقات الويب. نظراً لأن الاتصال بالسيرفر يستغرق وقتاً وغير مضمون النتيجة دائماً، يجب تصميم واجهة المستخدم لنتعامل مع 3 حالات متغيرة أساسية:

  1. حالة الانتظار (Loading): أثناء جلب البيانات.
  2. حالة النجاح (Success Data): عند وصول البيانات بنجاح.
  3. حالة الفشل (Error): في حال انقطاع الإنترنت أو وجود خطأ بالسيرفر.

1. الهيكل الأساسي للتعامل مع الثلاث حالات

نحتاج إلى 3 حالات داخل المكون للسيطرة الكاملة على الشاشة:

javascript
1function CourseList() {
2 const [courses, setCourses] = useState([]); // 1. البيانات
3 const [isLoading, setIsLoading] = useState(true); // 2. جاري التحميل
4 const [error, setError] = useState(null); // 3. الخطأ
5
6 useEffect(() => {
7 // جلب البيانات من الـ API
8 fetch('https://api.nouvil.net/courses')
9 .then((res) => {
10 if (!res.ok) throw new Error('فشل في جلب قائمة الكورسات');
11 return res.json();
12 })
13 .then((data) => {
14 setCourses(data);
15 setIsLoading(false); // إيقاف التحميل عند النجاح
16 })
17 .catch((err) => {
18 setError(err.message);
19 setIsLoading(false); // إيقاف التحميل حتى عند الفشل
20 });
21 }, []);
22
23 // التعامل مع الواجهة بحسب الحالة الحالية
24 if (isLoading) return <div>جاري تحميل الكورسات...</div>;
25 if (error) return <div>حدث خطأ: {error}</div>;
26
27 return (
28 <ul>
29 {courses.map((course) => (
30 <li key={course.id}>{course.title}</li>
31 ))}
32 </ul>
33 );
34}

2. استخدام async/await بأسلوب نظيف

دالة useEffect نفسها لا يمكن أن تكون async مباشرة! لأن دالة الـ Effect يجب أن ترجع دالة تنظيف (Cleanup Function) فقط أو لا ترجع شيئاً.

الطريقة الخاطئة:

الطريقة الخاطئة:
1// خطأ قاتل! لا تجعل دالة useEffect من نوع async
2useEffect(async () => {
3 const res = await fetch('...');
4}, []);

الطريقة الصحيحة

الطريقة الصحيحة
1useEffect(() => {
2 const fetchCourses = async () => {
3 try {
4 const res = await fetch('https://api.nouvil.net/courses');
5 const data = await res.json();
6 setCourses(data);
7 } catch (err) {
8 setError(err.message);
9 } finally {
10 setIsLoading(false); // يُنفذ دائماً سواء نجح أو فشل
11 }
12 };
13
14 fetchCourses();
15}, []);

3. إلغاء الطلبات المعلقة (AbortController)

إذا قام المستخدم بالتنقل بين الصفحات بسرعة قبل أن يكتمل طلب الـ API، سيحاول الكود التعديل على useState لمكون تم تدميره وإزالته من الـ DOM (Unmounted Component). لحل هذه المشكلة هندسياً، نستخدم AbortController لإلغاء طلب الشبكة داخل دالة التنظيف (Cleanup Function):

AbortController

AbortController
1useEffect(() => {
2 const controller = new AbortController();
3
4 async function loadData() {
5 try {
6 const res = await fetch('https://api.nouvil.net/courses', {
7 signal: controller.signal // ربط الطلب بـ AbortSignal
8 });
9 const data = await res.json();
10 setCourses(data);
11 } catch (err) {
12 if (err.name !== 'AbortError') {
13 setError(err.message); // إهمال الخطأ إذا كان سببه إلغاء الطلب يدوياً
14 }
15 }
16 }
17
18 loadData();
19
20 // إيقاف الطلب فوراً إذا خرج المستخدم من الصفحة قبل اكتماله
21 return () => controller.abort();
22}, []);

تأكد دائماً من تنظيف حالة الخطأ (Reset Error State) قبل البدء في طلب جديد!

ℹ️ معلومة

إذا كان لديك زر مثل "إعادة المحاولة" أو استعلام يعتمد على متغير مثل برامتر البحث [searchQuery]، تذكر دائماً تصفير حالة الخطأ وإعادة حالة التحميل للوضع المباشر قبل إطلاق الطلب الجديد:

الصياغة (Syntax)

syntax
1const handleRetry = () => {
2 setError(null); // 1. مسح الخطأ القديم
3 setIsLoading(true); // 2. تفعيل مؤشر التحميل
4 // 3. إعادة استدعاء دالة الجلب...
5};

نصائح احترافية

  • —بدون تصفير الخطأ، قد تظل رسالة الفشل القديمة معروضة في الشاشة أثناء جلب البيانات الجديدة، مما يسبب ارتباكاً كبيراً للمستخدم.

الدرس السابق

مفهوم التأثيرات الجانبية useEffect

الدرس التالي

Building Custom Hooks

نوفيل

منصة تعليم البرمجة الأولى بالعربي. تعلم من الصفر حتى الاحتراف مع كورسات احترافية وتحديات ذكاء اصطناعي.

المنصة

  • الكورسات
  • التحديات
  • المقالات
  • الأدوات

الحساب

  • إنشاء حساب
  • تسجيل الدخول
  • لوحة التحكم
  • الملف الشخصي

روابط

  • سياسة الخصوصية
  • شروط الاستخدام
  • عن نوفيل
  • تواصل معنا

© 2026 نوفيل. جميع الحقوق محفوظة.

صُنع بـ في مصر