عرض البيانات باستخدام الخصائص (Props)

حتى الآن، إذا أردت إعادة استخدام مكون <Header />، فسيعرض نفس المحتوى في كلتا الحالتين.

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

ولكن ماذا لو أردت تمرير نص مختلف أو كنت لا تعرف المعلومات مسبقًا لأنك تقوم بجلب البيانات من مصدر خارجي؟

تحتوي عناصر HTML العادية على سمات (attributes) يمكنك استخدامها لتمرير قطع من المعلومات التي تغير سلوك تلك العناصر. على سبيل المثال، تغيير سمة src لعنصر <img> يغير الصورة المعروضة. تغيير سمة href لعلامة <a> يغير وجهة الرابط.

بنفس الطريقة، يمكنك تمرير قطع من المعلومات كخصائص (properties) إلى مكونات React. تسمى هذه props. خذ على سبيل المثال الاختلافات المحتملة لزر:

مخطط يظهر 3 اختلافات لمكون زر: أساسي، ثانوي، ومعطل

على غرار دالة JavaScript، يمكنك تصميم مكونات تقبل وسائط مخصصة (أو props) تغير سلوك المكون أو ما يتم عرضه عند تقديمه على الشاشة. ثم يمكنك تمرير هذه الخصائص من المكونات الأب إلى المكونات الابن.

ملاحظة: في React، تتدفق البيانات إلى أسفل شجرة المكونات. يُشار إلى هذا باسم تدفق البيانات أحادي الاتجاه. الحالة (State)، والتي سيتم مناقشتها في الفصل التالي، يمكن تمريرها من المكونات الأب إلى المكونات الابن كخصائص (props).

استخدام الخصائص (props)

في مكون HomePage الخاص بك، يمكنك تمرير خاصية title مخصصة إلى مكون Header، تمامًا كما تفعل مع سمات HTML:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

ويمكن لمكون Header، وهو المكون الابن، قبول هذه الخصائص كأول معامل دالة له:

index.html
function Header(props) {
  return <h1>Develop. Preview. Ship.</h1>;
}

إذا قمت باستخدام console.log() للخصائص، يمكنك أن ترى أنها كائن يحتوي على خاصية title.

index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

بما أن props هو كائن، يمكنك استخدام تفكيك الكائن لتسمية قيم props بشكل صريح داخل معاملات الدالة:

index.html
function Header({ title }) {
  console.log(title); // "React"
  return <h1>Develop. Preview. Ship.</h1>;
}

ثم يمكنك استبدال محتوى علامة <h1> بمتغير title الخاص بك.

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

إذا فتحت الملف في المتصفح، ستلاحظ أنه يعرض الكلمة الفعلية "title". هذا لأن React تعتقد أنك تنوي عرض سلسلة نصية عادية في DOM.

تحتاج إلى طريقة لإخبار React أن هذا متغير JavaScript.

استخدام المتغيرات في JSX

لاستخدام خاصية title، أضف الأقواس المعقوفة {}. هذه عبارة عن صيغة JSX خاصة تسمح لك بكتابة JavaScript عادي مباشرة داخل ترميز JSX الخاص بك.

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

يمكنك التفكير في الأقواس المعقوفة كطريقة للدخول إلى "أرض JavaScript" بينما أنت في "أرض JSX". يمكنك إضافة أي تعبير JavaScript (شيء يُقيّم إلى قيمة واحدة) داخل الأقواس المعقوفة. على سبيل المثال:

  1. خاصية كائن مع تدوين النقطة:
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. قالب نصي (template literal):
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. القيمة المرجعة من دالة:
example.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. أو المشغلات الثلاثية (ternary operators):
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

يمكنك الآن تمرير أي سلسلة نصية إلى خاصية title الخاصة بك، أو إذا استخدمت المشغل الثلاثي، يمكنك حتى عدم تمرير خاصية title على الإطلاق، حيث أنك قد أخذت في الاعتبار الحالة الافتراضية في مكونك:

example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

يقبل مكونك الآن خاصية title عامة يمكنك إعادة استخدامها في أجزاء مختلفة من تطبيقك. كل ما عليك فعله هو تغيير سلسلة title:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

التكرار عبر القوائم

من الشائع أن يكون لديك بيانات تحتاج إلى عرضها كقائمة. يمكنك استخدام طرق المصفوفات لمعالجة بياناتك وإنشاء عناصر واجهة مستخدم متطابقة في النمط ولكنها تحتوي على قطع مختلفة من المعلومات.

أضف مصفوفة الأسماء التالية إلى مكون HomePage الخاص بك:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

ثم يمكنك استخدام طريقة array.map() للتكرار عبر المصفوفة واستخدام دالة السهم لتعيين اسم إلى عنصر قائمة:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

لاحظ كيف استخدمت الأقواس المعقوفة للتنقل بين "JavaScript" و "JSX".

إذا قمت بتشغيل هذا الكود، سيعطينا React تحذيرًا حول فقدان خاصية key. هذا لأن React تحتاج إلى شيء لتحديد العناصر في المصفوفة بشكل فريد حتى تعرف أي العناصر يجب تحديثها في DOM.

يمكنك استخدام الأسماء الآن لأنها فريدة حاليًا، ولكن يُوصى باستخدام شيء مضمون أن يكون فريدًا، مثل معرف العنصر.

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

موارد إضافية: