انتقل إلى محتوى الدرس
الدرس 40
دورة ReactJS

إرسال وتحديث وحذف البيانات عبر طلبات HTTP في ReactSending POST PUT and DELETE Requests in React

أرسل طلبات الإنشاء والتحديث والحذف عبر أفعال POST وPUT وDELETE من دوال الأحداث في React مع تعطيل الأزرار أثناء الحفظ والتراجع الآمن وحماية جلسات المصادقة.
أقسام الدرس
6
الأمثلة
3
اللغة
العربية
تاريخ النشر
غير محدد
المشاهدات
0
محتوى الدرس
في هذا الدرس 6تصفّح المواضيع

درست سابقاً الفارق المعماري الجوهري بين التأثيرات ومعالجات الأحداث: فخطاف useEffect() يزامن البيانات لمجرد ظهور المكون على الشاشة، أما عمليات تعديل البيانات مثل إنشاء سجل بـ POST أو تحديثه بـ PUT أو حذفه بـ DELETE فتنطلق استجابةً لفعل صريح ومقصود من المستخدم عند إرسال نموذج أو نقر زر.

نفّذ جميع طلبات الكتابة والتعديل داخل دوال أحداث غير متزامنة مثل async function handleSubmit(e)، ولا تضعها داخل useEffect() أبداً حتى لا تتكرر عمليات الإرسال تلقائياً أثناء التطوير أو عند تغير حالة جانبية.

لإرسال بيانات نموذج بصيغة JSON عبر طلب POST، ابدأ باستدعاء e.preventDefault() لمنع المتصفح من إعادة تحميل الصفحة. ثم مرّر كائن الإعدادات إلى fetch() متضمناً method: 'POST'، وتحديد نوع المحتوى في رؤوس HTTP عبر headers: { 'Content-Type': 'application/json' }، وتحويل الكائن لنص عبر body: JSON.stringify(payload).

وبعد التحقق من نجاح response.ok، اقرأ السجل العائد من الخادم (الذي يحمل المعرّف الرسمي المولّد id) وأضفه بنقاء إلى مصفوفة الحالة عبر التحديث الدالي setTasks((prev) => [...prev, createdTask]).

HTML
const res = await fetch('/api/tasks', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title, done: false }),
});
if (!res.ok) throw new Error('Create failed');
const created = await res.json();
setTasks((prev) => [...prev, created]);

لتعديل سجل قائم نرسل طلب method: 'PUT' أو 'PATCH' إلى عنوان المورد المحدد مثل /api/tasks/t-1، وفور نجاح الاستجابة نستبدل الكائن المعدّل داخل مصفوفة الحالة بنقاء عبر الدالة prev.map((item) => item.id === updated.id ? updated : item).

ولحذف سجل نرسل طلب method: 'DELETE' إلى عنوانه، وبعد التحقق من response.ok نستبعده من الواجهة عبر prev.filter((item) => item.id !== id).

مخطط يوضح أفعال تعديل البيانات الثلاثة من معالجات الأحداث في React: الإنشاء بـ POST والتعديل بـ PUT والحذف بـ DELETE
HTML
// Update with PUT + map:
setTasks((prev) =>
  prev.map((t) => (t.id === updated.id ? updated : t))
);
// Delete with DELETE + filter:
setTasks((prev) => prev.filter((t) => t.id !== id));

يميل المستخدمون في الشبكات البطيئة إلى النقر المزدوج على زر الحفظ إذا لم يظهر تغير بصري فوري. وبما أن طلبات POST غير متكافئة التكرار، فإن إرسال طلبين متتاليين ينشئ سجلين مكررين في قاعدة البيانات.

حصّن كل نموذج بطبقتين متكاملتين: افحص if (isSubmitting) return; في مطلع دالة الإرسال (لمنع تكرار مفتاح الإدخال Enter أيضاً)، واربط السمة disabled={isSubmitting} بزر <button> مع تبديل نصه إلى «جاري الحفظ...» وإعادته داخل كتلة finally مضمونة التنفيذ.

في التفاعلات السريعة كتبديل حالة إنجاز مهمة أو حفظ عنصر في المفضلة، قد يبدو انتظار استجابة الشبكة بطيئاً. يعتمد نمط التحديث المتفائل (Optimistic UI) على تحديث الحالة المحلية في الواجهة فوراً، مع الاحتفاظ المسبق بنسخة المرجع الأصلي const previousTasks = tasks.

فإذا فشل الطلب في الخلفية أو رد الخادم بخطأ، نستعيد النسخة السابقة فوراً عبر setTasks(previousTasks) ونعرض تنبيهاً صادقاً يوضح تعذر الحفظ الفعلي.

HTML
const snapshot = tasks;
setTasks((prev) =>
  prev.map((t) =>
    t.id === id ? { ...t, done: !t.done } : t
  )
);
const res = await fetch(url, { method: 'PUT', body });
if (!res.ok) {
  setTasks(snapshot);
  setRollbackNotice('Save failed — reverted!');
}

تتطلب طلبات التعديل المحمية إثبات هوية المستخدم للخادم. تجنب تخزين رموز الجلسات الحساسة أو مفاتيح المصادقة طويلة الأمد داخل window.localStorage؛ لأن أي كود JavaScript يعمل في الصفحة يستطيع قراءته، مما يجعل أي ثغرة برمجة نصية عابرة للمواقع XSS كفيلة بتسريب جلسات المستخدمين.

المعيار الأمني الأرقى هو اعتماد كوكيز الجلسة المزودة بسمات HttpOnly; Secure; SameSite مع حماية CSRF؛ إذ يرسلها المتصفح تلقائياً مع credentials: 'same-origin' بينما تظل محجوبة تماماً عن قراءة السكريبتات. يلخص الجدول التالي قواعد عمليات التعديل:

عملية الشبكةإعداد دالة fetch<code>()مزامنة مصفوفة الحالة في React
إنشاء سجل جديدmethod: 'POST' مع جسم JSONإلحاق السجل العائد من الخادم عبر [...prev, created]
تحديث سجل قائمmethod: 'PUT' أو 'PATCH' مع جسم JSONاستبدال السجل المطابق بنقاء عبر prev.map<code>()
حذف سجل محددmethod: 'DELETE' على عنوان المورداستبعاد المعرّف المحذوف عبر prev.filter<code>()
توثيق الجلسةcredentials: 'same-origin' مع كوكيز HttpOnlyحفظ تفضيلات العرض فقط ومنع تخزين الرموز السرية في localStorage
خلاصة المعرفة ومحطة الانتقال

ملخص الدرس

حصاد الدرس

مراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي

ماذا تعلّمت في هذا الدرس؟

أتقنت في هذا الدرس إرسال طلبات POST وPUT وDELETE من دوال الأحداث في React، ومزامنة الحالة بنقاء عبر map وfilter، ومنع الإرسال المكرر براية isSubmitting، وتطبيق التحديث المتفائل مع التراجع الآمن، وحماية جلسات المصادقة بكوكيز HttpOnly. الخطوة التالية: انتقل الآن إلى الدرس رقم 41 «بناء الخطافات المخصصة Custom Hooks لإعادة استخدام المنطق» لمواصلة البناء التراكمي المتدرج في مسار React الحديث.

مشاركة

هل كان هذا الدرس مفيدًا؟

جارٍ تحميل الآراء…

ابنِ لغتك البرمجية

المصطلحات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 HTTP Mutation طلب تعديل البيانات
طلب شبكة يغيّر البيانات المخزنة على الخادم مثل الإنشاء أو التحديث أو الحذف استجابة لفعل المستخدم.
للمراجعة
02 Optimistic UI التحديث المتفائل للواجهة
تحديث الواجهة فورياً قبل اكتمال رد الخادم مع الاحتفاظ بنسخة سابقة لاسترجاعها تلقائياً إذا فشل الحفظ.
للمراجعة
03 Pending Guard حارس قيد الإرسال
متغير حالة مثل isSubmitting يعطّل زر الحفظ ويمنع تكرار إرسال النموذج أثناء انتظار استجابة الخادم.
للمراجعة
04 HttpOnly Cookie كوكيز محمية HttpOnly
سمة أمنية تجعل المتصفح يرسل ملف الارتباط تلقائياً مع الطلبات ويحجبه تماماً عن قراءة أكواد JavaScript.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

حروف قليلة. معنى كامل.

الاختصارات4

راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.

0 / 4 مفهومةأول بطاقة، أول خطوة
01 CRUD CRUD
Create, Read, Update, Delete
العمليات الأربع الأساسية لإدارة البيانات الدائمة والمرتبطة بأفعال POST وGET وPUT وDELETE.
للمراجعة
02 XSS XSS
Cross-Site Scripting
ثغرة حقن برمجيات نصية تمكّن المهاجم من قراءة أي رموز سرية مخزنة بشكل مكشوف في localStorage.
للمراجعة
03 CSRF CSRF
Cross-Site Request Forgery
تزوير الطلبات عبر المواقع والذي يُصدّ بسياسات SameSite ورموز التحقق الأمنية الخاصة بالجلسة.
للمراجعة
04 JWT JWT
JSON Web Token
صيغة رموز مصادقة موقّعة رقمياً تتطلب حماية صارمة من الوصول المباشر عبر السكريبتات.
للمراجعة

اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.

من الفهم للتطبيق

مهامك قبل الاختبار

خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.

0/2مهام منجزة
  1. افتح مثال TaskCreator في محرر التجريب وأضف مهمتين جديدتين وراقب تحول زر الإضافة إلى Saving... أثناء الإرسال.

  2. افتح مثال OptimisticChecklist في محرر التجريب وجرّب تبديل مهمة مع تفعيل محاكاة الفشل لمشاهدة التراجع التلقائي، ثم ألغِ المحاكاة للحفظ الفعلي.

تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.

مساحة التحدي

اختبر فهمك.
ووصلها للإتقان.

كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.

10أسئلة 2أنواع تحديات 100%هدف الإتقان
تصحيح تلقائي. فرص بلا حدود.

أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.

الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.

لمحة عن التحدي10 أسئلة تنتظرك
01

أين يجب تنفيذ طلبات التعديل POST وPUT وDELETE داخل مكون React؟

تنطلق عمليات التعديل استجابةً لفعل صريح من المستخدم لذا مكانها الصحيح داخل دوال الأحداث مثل onSubmit وonClick.

02

أي حقل في رؤوس HTTP يخبر الخادم بأن جسم الطلب المُرسل عبر fetch() منسق بصيغة JSON؟

يعلن الرأس Content-Type بقيمة application/json أن البيانات المرسلة بصيغة JSON.

03

عند تمرير كائن JavaScript كجسم لطلب POST في fetch() يجب تحويله إلى نص عبر JSON.stringify(payload).

صواب؛ لأن تمرير الكائن الخام دون JSON.stringify يحوله إلى النص غير الصالح "[object Object]".

04

بعد نجاح طلب الحذف DELETE للمهمة t-2 على الخادم، كيف تزيلها بنقاء من مصفوفة الحالة في React؟

باستخدام التحديث الدالي مع filter لاستبعاد العنصر المحذوف دون تعديل المصفوفة الأصلية.

05

لماذا يوضع السطر setIsSubmitting(false) داخل كتلة finally بدلاً من نهاية كتلة try فقط؟

لأنه عند فشل الطلب والانتقال إلى catch، تضمن finally إعادة تفعيل الزر ليتمكن المستخدم من المحاولة مجدداً.

06

يتطلب التحديث المتفائل دائماً الاحتفاظ بنسخة من الحالة السابقة للتراجع الفوري إليها إذا رفض الخادم التعديل.

صواب؛ فبدون نسخة التراجع ستظهر للمستخدم بيانات غير محفوظة فعلياً على الخادم عند الفشل.

07

في أي عملية مما يلي يُعد التحديث المتفائل خياراً هندسياً غير مناسب وخطراً؟

عمليات الدفع المالي والحجوزات الحرجة تتطلب انتظار التأكيد الرسمي من الخادم قبل إظهار النجاح.

08

لماذا يُعد تخزين رموز جلسات المصادقة الحساسة داخل window.localStorage مخاطرة أمنية؟

لأن أي كود JavaScript يعمل في الصفحة، بما في ذلك ثغرات XSS، يستطيع قراءة localStorage وسرقة الرمز السري.

09

ملفات الارتباط المزودة بسمة HttpOnly لا يمكن قراءتها عبر document.cookie في JavaScript مما يحميها من سرقة XSS.

صواب؛ يتولى المتصفح إرسالها في طبقة الشبكة دون كشف قيمتها لأي سكريبت في الصفحة.

10

أي دالة مصفوفات نقية تستبدل كائناً محدّثاً واحداً داخل الحالة مع الإبقاء على بقية العناصر دون تغيير؟

تعيد الدالة map() مصفوفة جديدة يُستبدل فيها السجل المطابق فقط بنقاء.