Kodokon kodokon.com

رفع الحالة ومشاركة البيانات

ضع كل جزء من الحالة في أقرب سلف مشترك لمشاركة البيانات بين عدة مكوّنات دون تكرارها.

7 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

يحتاج مكوّنان شقيقان إلى عرض البيانات نفسها: حقل بحث والقائمة التي يصفّيها، مثلاً. لا يمكن أن تنجح الحالة المحلية في كل منهما، لأنهما لا يستطيعان رؤية بعضهما. الحل هو رفع الحالة إلى أقرب سلف مشترك بينهما: يمتلك الأب البيانات ويعيدها إلى الأسفل عبر الـ props.

JSX
import { useState } from "react";

function ProductPage({ products }) {
  const [query, setQuery] = useState("");

  return (
    <>
      <SearchBar query={query} onChange={setQuery} />
      <ProductList products={products} query={query} />
    </>
  );
}
يمتلك الأب query ويشاركها مع كلا الابنين.

عندئذ يصبح الابنان مكوّنين متحكماً بهما: يستقبلان القيمة للقراءة فقط، ولتغييرها يستدعيان دالة الاستدعاء الراجع (callback) التي يوفرها الأب. تتدفق البيانات نزولاً عبر الـ props، وتتدفق طلبات التغيير صعوداً عبر الدوال. هذا التدفق أحادي الاتجاه يجعل سلوك التطبيق سهل المتابعة.

JSX
function SearchBar({ query, onChange }) {
  return (
    <input
      value={query}
      onChange={(e) => onChange(e.target.value)}
      placeholder="Search for a product"
    />
  );
}

function ProductList({ products, query }) {
  const visible = products.filter((p) =>
    p.name.toLowerCase().includes(query.toLowerCase())
  );
  return (
    <ul>
      {visible.map((p) => <li key={p.id}>{p.name}</li>)}
    </ul>
  );
}
يطلب SearchBar التغيير، ويعكسه ProductList.

يجب أن يكون لكل قطعة من البيانات مصدر حقيقة وحيد. إذا خزّن مكوّنان نسخته الخاصة من الحالة نفسها، فستتباعد النسختان في النهاية: تُحدَّث إحداهما، والأخرى لا، فتصبح الواجهة غير متسقة. رفع الحالة يزيل هذا الخطر. وعندما يتعين على البيانات عبور مستويات عديدة، يخفف التركيب (الدرس التالي) ثم الـ context من تمرير الـ props.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. أين يجب أن تضع الحالة التي يحتاجها مكوّنان شقيقان؟
    • في أول الشقيقين، الذي يمررها إلى الآخر
    • في أقرب سلف مشترك بينهما
    • في متغير عام مُعرّف خارج React
    • في كل من الشقيقين، مع مزامنتها يدوياً
  2. كيف يمكن لمكوّن ابن أن يعدّل حالة يملكها الأب؟
    • بتعديل الـ prop المستقبَل مباشرة
    • باستدعاء دالة استدعاء راجع (callback) مرّرها الأب كـ prop
    • باستخدام useState بنفس القيمة الأولية التي لدى الأب
  3. لماذا تتجنب تخزين البيانات نفسها في قطعتَي حالة مختلفتين؟
    • لأنها تستهلك ذاكرة كثيرة جداً
    • لأن React تمنع استدعاءَي useState بنفس القيمة الأولية
    • لأن النسختين تخرجان في النهاية عن التزامن وتصبح الواجهة غير متسقة