تمرير الخصائص إلى مكوّن
تستخدم مكوّنات React “الخصائص” (props) للتواصل مع بعضها البعض. يمكن لكل مكوّن أب تمرير بعض المعلومات إلى مكوّناته الفرعية عن طريق إعطائها الخصائص. قد تذكرك الخصائص بسمات HTML، ولكن يمكنك تمرير أي قيمة JavaScript من خلالها، بما في ذلك الكائنات والمصفوفات والدوال.
You will learn
- كيفية تمرير الخصائص (props) إلى المكوّنات (Components)
- كيفية قراءة الخصائص من مكوّن
- كيفية تحديد القيم الافتراضية للخصائص
- كيفية تمرير بعض عناصر JSX إلى مكوّن
- كيف تتغير الخصائص مع مرور الوقت
الخصائص المألوفة
الخصائص هي المعلومات التي تمررها إلى وسم JSX . على سبيل المثال، className
، src
، alt
، width
، و height
هي بعض الخصائص التي يمكنك تمريرها إلى <img>
:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Lin Lanying" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
الخصائص التي يمكن تمريرها إلى وسم <img>
هي خصائص محدده مسبقًا (ReactDOM يتوافق مع معيار الHTML). ولكن يمكنك تمرير أي خصائص إلى المكوّنات الخاصة بك، مثل <Avatar>
، لتخصيصها. هنا كيفية ذلك!
تمرير الخصائص إلى مكوّن
في هذا الكود، مكوّن ال Profile
لا يمرر أي خصائص إلى مكوّنه الطفل، Avatar
:
export default function Profile() {
return (
<Avatar />
);
}
يمكنك إعطاء Avatar
بعض الخصائص في خطوتين.
الخطوة الأولى: تمرير الخصائص إلى مكوّن طفل
أولاً، يجب تمرير بعض الخصائص إلى Avatar
. على سبيل المثال، دعونا نمرر خاصيتين: person
(كائن)، و size
(رقم):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying'، imageId: '1bX5QH6' }}
size={100}
/>
);
}
الآن يمكنك قراءة هذه الخصائص داخل مكوّن الAvatar
.
الخطوة الثانية: اقرأ الخصائص داخل المكّون الطفل
يمكنك قراءة هذه الخصائص عن طريق كتابة أسمائها person, size
مفصولة بفواصل داخل ({
و })
مباشرة بعد function Avatar
. هذا يتيح لك استخدامها داخل كود Avatar
، كما تفعل مع المتغيرات.
function Avatar({ person, size }) {
// person و size متاحين هنا
}
أضف بعض المنطق إلى Avatar
باستخدام الخصائص person
و size
للتصيير، وبذلك تكون انتهيت.
الآن يمكنك تهيئة Avatar
للتصيير بطرق مختلفة مع خصائص مختلفة. جرب تعديل القيم!
import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'كاتسوكو ساروهاشي', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'أكليلو ليما', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'لين لانين', imageId: '1bX5QH6' }} /> </div> ); }
تتيح لك المكوّنات التفكير في المكوّنات الآباء والمكوّنات الأبناء بشكل مستقل. على سبيل المثال، يمكنك تغيير مكوّنات الperson
أو الsize
في داخل Profile
دون الحاجة للتفكير في كيفية استخدامهما في المكوّن المسمى Avatar
. بالمثل، يمكنك تغيير كيفية استخدام المكوّن Avatar
لهذه الخصائص دون النظر إلى المكوّن Profile
.
يمكنك التفكير في الخصائص على أنها “أدوات تعديل” يمكنك تعديلها. إنها تؤدي نفس الدور الذي تؤديه الوسائط للدوال - في الواقع، الخصائص هي الوسيطة الوحيدة لمكوّنك! تقبل دوال المكوّنات في React وسيطة واحدة فقط، كائن خصائص
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
عادةً ما لا تحتاج إلى كامل كائن الprops
نفسه، لذلك يتم تحليله إلى خصائص فردية.
تحديد قيمة افتراضية لخاصية
إذا كنت تريد إعطاء قيمة افتراضية لخاصية تستخدم عند عدم تحديد قيمة، يمكنك القيام بذلك باستخدام الصيغة التحليلية عن طريق وضع علامة =
والقيمة الافتراضية مباشرة بعد المعامل:
function Avatar({ person, size = 100 }) {
// ...
}
الآن، إذا تم عرض <Avatar person={...} />
بدون خاصية size
،سيتم تعيين الsize
على 100
.
تُستخدم القيمة الافتراضية فقط إذا كانت خاصية الsize
مفقودة أو إذا قمت بتمرير size={undefined}
. ولكن إذا قمت بتمرير size={null}
أو size={0}
، فلن يتم استخدام القيمة الافتراضية.
إعادة توجيه الخصائص باستخدام صيغة الانتشار (spread operator) في JSX
في بعض الأحيان، يصبح تمرير الخصائص مُكررًا جدًا:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
لا يوجد أي شيء خاطئ في تكرار الكود - بل يمكن أن يزيد الوضوح. ولكن في بعض الأحيان قد يُفَضّل الاختصار. تقوم بعض المكوّنات بتوجيه جميع خصائصها إلى أطفالها، مثل الطريقة التي يفعل بها Profile
مع Avatar
. نظرًا لعدم استخدامها لأي من خصائصها مباشرة، فقد يكون من المنطقي استخدام صيغة الانتشار “spread” الأكثر اختصارًا:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
يقوم هذا بتوجيه جميع خصائص Profile
إلى Avatar
دون تسمية كل منها بشكل فردي.
استخدم صيغة انتشار بحذر. إذا كنت تستخدمها في كل مكوّن آخر، فهناك شيء خاطئ. غالبًا ما يشير ذلك إلى أنه يجب تقسيم المكوّنات الخاصة بك وتمرير الأطفال كـ JSX. المزيد حول ذلك في القسم التالي!
تمرير JSX كأطفال
من الشائع تضمين أوسمّة المتصفح المدمجة:
<div>
<img />
</div>
في بعض الأحيان ستريد تضمين مكوّناتك الخاصة بنفس الطريقة:
<Card>
<Avatar />
</Card>
عند تضمين محتوى داخل وسم JSX، سيتلقى المكوّن الأب هذا المحتوى في خاصية تسمى children
. على سبيل المثال، سيتلقى المكوّن Card
القادم خاصية children
التي تم تعيينها على <Avatar />
و يقوم بعرضها في قسم مجمع
import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'كاتسوكو ساروهاشي', imageId: 'YfeOqp2' }} /> </Card> ); }
جرب استبدال <Avatar>
داخل <Card>
بنص ما لمعرفة كيف يمكن للمكوّن Card
لف أي محتوى متداخل. لا يحتاج المكوّن إلى “معرفة” ما يتم تقديمه داخله. سترى هذه النمط المرن في العديد من الأماكن.
يمكنك التفكير في المكوّن الذي يحتوي على خاصية children
على أنه لديه “ثقب” يمكن “ملؤه” من قِبَل مكوّناته الأبويه بأي JSX. سوف تستخدم في كثير من الأحيان خاصية children
للتغليف البصري: اللوحات، الشبكات، إلخ.
Illustrated by Rachel Lee Nabors
كيفية تغيير الخصائص مع مرور الوقت
يتلقى المكوّن Clock
القادم خاصيتين من مكوّنه الأب: color
و time
. (تم حذف كود المكوّن الأب لأنه يستخدم الحالة state، التي لا نريد أن نتعمق فيها الآن.)
جرب تغيير اللون في مربع الاختيار أدناه:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
يوضح هذا المثال أنه يمكن للمكوّن أن يتلقى خصائص مختلفة مع مرور الوقت. الخصائص ليست دائمًا ثابتة! هنا، تتغير الخاصية time
كل ثانية، وتتغير الخاصية color
عندما تختار لونًا آخر. تعكس الخصائص بيانات المكوّن في أي نقطة من الزمن، عوضاً عن البدايه فقط.
ومع ذلك، تكون الخصائص immutable—وهو مصطلح من علم الحوسبة يعني “لا يمكن تغييره”. عندما يحتاج المكوّن إلى تغيير خصائصه (على سبيل المثال، ردًا على تفاعل من المستخدم أو بيانات جديدة)، سيضطر إلى “طلب” من مكوّنه الأب تمريره خصائص مختلفة—كائن جديد! سيتم رفض الخصائص القديمة ثم سيستعيد محرك JavaScript في نهاية المطاف الذاكرة التي استهلكتها.
**لا تحاول “تغيير الخصائص”. ** عندما تحتاج إلى الاستجابة لإدخال المستخدم (مثل تغيير اللون المحدد)، ستحتاج إلى “تعيين الحالة”، والتي يمكنك التعرف عليها في الحالة: ذاكرة المكوّن.
Recap
- لتمرير الخصائص، أضفها إلى JSX، تمامًا كما تفعل مع سمات HTML.
- لقراءة الخصائص، استخدم
function Avatar({ person, size })
صيغة تحليل. - يمكنك تحديد قيمة افتراضية مثل
size = 100
، التي تُستخدم في الخصائص الناقصة وغير المُعرّفة ‘undefined’. - يمكنك توجيه جميع الخصائص باستخدام صيغة الانتشار
<Avatar {...props} />
، ولكن لا تستخدمها بكثرة! - JSX المتداخل مثل
<Card><Avatar /></Card>
سيظهر كخاصيةchildren
للمكوّنCard
. - تمثل الخصائص لقطات للقراءة فقط في الوقت: يتلقى كل عرض نسخة جديدة من الخصائص.
- لا بمكنك تغيير الخصائص. عندما تحتاج إلى التفاعلية، ستحتاج إلى تعيين الحالة.
Challenge 1 of 3: استخراج مكوّن
يحتوي مكوّن Gallery
هذا على بعض الmarkup المماثلة جدًا لاثنين من الملفات. استخرِج مكوّن الProfile
منه لتقليل التكرار. سوف تحتاج إلى اختيار الخصائص التي ستمررها إليه.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>العلماء البارزون</h1> <section className="profile"> <h2>ماري سكاوندوڤسكا-كوري</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Maria Skłodowska-Curie" width={70} height={70} /> <ul> <li> <b>المهنة: </b> عالمة فيزياء وكيمياء </li> <li> <b>الجوائز: 4 </b> (جائزة نوبل في الفيزياء، جائزة نوبل في الكيمياء، ميدالية دافي، ميدالية ماتيوتشي) </li> <li> <b>اكتشفت: </b> البولونيوم (عنصر كيميائي) </li> </ul> </section> <section className="profile"> <h2>كاتسوكو ساروهاشى</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Katsuko Saruhashi" width={70} height={70} /> <ul> <li> <b>المهنة: </b> جيوكيميائية </li> <li> <b>الجوائز: 2 </b> (جائزة مياكي للجيوكيمياء، جائزة تاناكا) </li> <li> <b>اكتشفت: </b> طريقة لقياس ثاني أكسيد الكربون في المياه البحرية </li> </ul> </section> </div> ); }