الفرق بين المراجعتين لصفحة: «React/composition vs inheritance»
Kinan-mawed (نقاش | مساهمات) لا ملخص تعديل |
تحديث |
||
(4 مراجعات متوسطة بواسطة 3 مستخدمين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:الفرق بين التركيب والوراثة في React}}</noinclude> | <noinclude>{{DISPLAYTITLE:الفرق بين التركيب والوراثة في React}}</noinclude> | ||
تمتلك React | تمتلك React نموذجًا قويًّا للتركيب (composition) ونُوصي باستخدام التركيب بدلًا من الوراثة (inheritance) لإعادة استخدام الشيفرة بين المُكوِّنات. | ||
سننظر في هذا القسم إلى بعض المشاكل التي بسببها قد يستخدم المُطوِّر الجديد على React الوراثة، وسنرى كيفيّة حلّها باستخدام التركيب. | سننظر في هذا القسم إلى بعض المشاكل التي بسببها قد يستخدم المُطوِّر الجديد على React الوراثة، وسنرى كيفيّة حلّها باستخدام التركيب. | ||
== مفهوم الاحتواء == | == مفهوم الاحتواء == | ||
لا تعرف بعض المُكوِّنات العناصر الأبناء لها مُسبقًا، وهو | لا تعرف بعض المُكوِّنات العناصر الأبناء لها مُسبقًا، وهو أمرٌ شائعٌ بشكلٍ خاص بالنسبة لمُكوِّن القائمة الجانبيّة <code>Sidebar</code> أو مربّع الحوار <code>Dialog</code>. | ||
نُوصي بأن تستخدم تلك المُكوِّنات الخاصيّة <code>children</code> لتمرير العناصر بشكلٍ مباشر إلى ناتجها:<syntaxhighlight lang="javascript"> | |||
function FancyBorder(props) { | function FancyBorder(props) { | ||
return ( | return ( | ||
سطر 32: | سطر 32: | ||
</syntaxhighlight>[https://codepen.io/gaearon/pen/ozqNOV?editors=0010 جرّب المثال على موقع CodePen]. | </syntaxhighlight>[https://codepen.io/gaearon/pen/ozqNOV?editors=0010 جرّب المثال على موقع CodePen]. | ||
يُمرَّر أي شيء بداخل العنصر <code><FancyBorder></code> إلى المُكوِّن <code>FancyBorder</code> عبر الخاصيّة <code>children</code>. | يُمرَّر أي شيء بداخل العنصر <code><FancyBorder></code> إلى المُكوِّن <code>FancyBorder</code> عبر الخاصيّة <code>children</code>. وبما أنّ المُكوِّن <code>FancyBorder</code> يُصيِّر <code>{props.children}</code> بداخل عنصر <code>[[HTML/div|<nowiki><div></nowiki>]]</code>، فستظهر العناصر المُمرَّرة بداخل الناتج النهائي. | ||
أحيانًا قد تحتاج إلى تمرير عناصر مُتعدِّدة. في تلك الحالات يجب أن تفعل ذلك بطريقتك الخاصّة بدلًا من استخدام <code>children</code>، كما يلي:<syntaxhighlight lang="javascript"> | أحيانًا قد تحتاج إلى تمرير عناصر مُتعدِّدة. في تلك الحالات يجب أن تفعل ذلك بطريقتك الخاصّة بدلًا من استخدام <code>children</code>، كما يلي:<syntaxhighlight lang="javascript"> | ||
سطر 84: | سطر 84: | ||
return ( | return ( | ||
<Dialog | <Dialog | ||
title=" | title="أهلًا" | ||
message="شكرًا لك لزيارة موقعنا" /> | message="شكرًا لك لزيارة موقعنا" /> | ||
سطر 92: | سطر 92: | ||
</syntaxhighlight>[https://codepen.io/gaearon/pen/kkEaOZ?editors=0010 جرّب المثال على موقع CodePen]. | </syntaxhighlight>[https://codepen.io/gaearon/pen/kkEaOZ?editors=0010 جرّب المثال على موقع CodePen]. | ||
يعمل التركيب | يعمل التركيب بشكلٍ مُماثل للمُكوِّنات المُعرَّفة كأصناف:<syntaxhighlight lang="javascript"> | ||
function Dialog(props) { | function Dialog(props) { | ||
return ( | return ( | ||
سطر 145: | سطر 145: | ||
يمنحك التركيب والخاصيّات <code>props</code> المرونة التي تحتاجها لتخصيص مظهر وسلوك المُكوِّنات بطريقة مضبوطة وآمنة. تذكّر أنّ المُكوّنات قد تستقبل خاصيّات من محتوى مُتعدِّد، مثل القيم المبدئية، وعناصر React، والدوال. | يمنحك التركيب والخاصيّات <code>props</code> المرونة التي تحتاجها لتخصيص مظهر وسلوك المُكوِّنات بطريقة مضبوطة وآمنة. تذكّر أنّ المُكوّنات قد تستقبل خاصيّات من محتوى مُتعدِّد، مثل القيم المبدئية، وعناصر React، والدوال. | ||
إن أردت إعادة استخدام بعض الوظائف بين المُكوِّنات غير المُتعلِّقة بواجهة المستخدم فنقترح استخراجها إلى واحدات JavaScript مُنفصِلة، حيث يُمكِن للمُكوِّن أن يستورد ويستخدم الدوال والكائنات والأصناف بدون | إن أردت إعادة استخدام بعض الوظائف بين المُكوِّنات غير المُتعلِّقة بواجهة المستخدم فنقترح استخراجها إلى واحدات JavaScript مُنفصِلة، حيث يُمكِن للمُكوِّن أن يستورد ويستخدم الدوال والكائنات والأصناف بدون الحاجة إلى تمديدها عن طريق الكلمة <code>extend</code>. | ||
== انظر أيضًا == | |||
* [[React/hello world|مثال أهلًا بالعالم في React]] | |||
* [[React/introducing jsx|مقدمة إلى JSX]] | |||
* [[React/rendering elements|تصيير العناصر]] | |||
* [[React/components and props|المكونات والخاصيات]] | |||
* [[React/state and lifecycle|حالة ودورة حياة المكونات]] | |||
* [[React/handling events|معالجة الأحداث في React]] | |||
* [[React/conditional rendering|التصيير الشرطي]] | |||
* [[React/lists and keys|القوائم والمفاتيح]] | |||
* [[React/forms|الحقول]] | |||
* [[React/lifting state up|رفع الحالات المشتركة للمستوى الأعلى]] | |||
* [[React/thinking in react|أسلوب التفكير في React]] | |||
== مصادر == | == مصادر == | ||
* [https://reactjs.org/docs/composition-vs-inheritance.html صفحة الفرق بين التركيب والوراثة في توثيق React الرسمي]. | * [https://reactjs.org/docs/composition-vs-inheritance.html صفحة الفرق بين التركيب والوراثة في توثيق React الرسمي]. | ||
[[تصنيف:React]] | |||
[[تصنيف:React Main Concepts]] |
المراجعة الحالية بتاريخ 07:02، 3 نوفمبر 2020
تمتلك React نموذجًا قويًّا للتركيب (composition) ونُوصي باستخدام التركيب بدلًا من الوراثة (inheritance) لإعادة استخدام الشيفرة بين المُكوِّنات.
سننظر في هذا القسم إلى بعض المشاكل التي بسببها قد يستخدم المُطوِّر الجديد على React الوراثة، وسنرى كيفيّة حلّها باستخدام التركيب.
مفهوم الاحتواء
لا تعرف بعض المُكوِّنات العناصر الأبناء لها مُسبقًا، وهو أمرٌ شائعٌ بشكلٍ خاص بالنسبة لمُكوِّن القائمة الجانبيّة Sidebar
أو مربّع الحوار Dialog
.
نُوصي بأن تستخدم تلك المُكوِّنات الخاصيّة children
لتمرير العناصر بشكلٍ مباشر إلى ناتجها:
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
يُتيح هذا للمُكوِّنات الأخرى بأن تُمرِّر عناصر أبناء لها عن طريق التداخل في JSX:
function WelcomeDialog() {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
أهلًا
</h1>
<p className="Dialog-message">
شكرًا لك لزيارة موقعنا
</p>
</FancyBorder>
);
}
يُمرَّر أي شيء بداخل العنصر <FancyBorder>
إلى المُكوِّن FancyBorder
عبر الخاصيّة children
. وبما أنّ المُكوِّن FancyBorder
يُصيِّر {props.children}
بداخل عنصر <div>
، فستظهر العناصر المُمرَّرة بداخل الناتج النهائي.
أحيانًا قد تحتاج إلى تمرير عناصر مُتعدِّدة. في تلك الحالات يجب أن تفعل ذلك بطريقتك الخاصّة بدلًا من استخدام children
، كما يلي:
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
إنّ عناصر React مثل <Contacts />
و <Chat />
هي مُجرّد كائنات، لذلك بإمكانك تمريرها كخاصيّات props
مثل أي بيانات أخرى. قد يُذكِّرك ذلك بمفهوم المداخل (slots) في مكتبات أخرى، ولكن لا توجد حدود لما يُمكِنك تمريره كخاصيّات props
في React.
التخصيص
أحيانًا نُفكّر بالمُكوِّنات على أنّها حالات خاصّة لمُكوِّنات أخرى، فمثلًا قد نقول أنّ مُكوِّن مربّع الترحيب WelcomeDialog
هو حالة خاصّة من مربّع الحوار Dialog
.
يُمكِن تحقيق ذلك في React عن طريق استخدام التركيب (composition) حيث يُصيِّر المُكوِّن الأكثر خصوصيّة المُكوِّن الأكثر عموميّة ويُعد له الخاصيّات:
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
function WelcomeDialog() {
return (
<Dialog
title="أهلًا"
message="شكرًا لك لزيارة موقعنا" />
);
}
جرّب المثال على موقع CodePen. يعمل التركيب بشكلٍ مُماثل للمُكوِّنات المُعرَّفة كأصناف:
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
}
class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
}
render() {
return (
<Dialog title="برنامج تسجيل الدخول"
message="كيف يمكننا الرجوع إليك؟">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
سجلّني في الموقع!
</button>
</Dialog>
);
}
handleChange(e) {
this.setState({login: e.target.value});
}
handleSignUp() {
alert(`أهلًا بك, ${this.state.login}!`);
}
}
إذًا ماذا عن الوراثة؟
نستخدم في فيسبوك آلاف مُكوِّنات React، ولم نجد أي حالة نُفضِّل فيها استخدام الوراثة.
يمنحك التركيب والخاصيّات props
المرونة التي تحتاجها لتخصيص مظهر وسلوك المُكوِّنات بطريقة مضبوطة وآمنة. تذكّر أنّ المُكوّنات قد تستقبل خاصيّات من محتوى مُتعدِّد، مثل القيم المبدئية، وعناصر React، والدوال.
إن أردت إعادة استخدام بعض الوظائف بين المُكوِّنات غير المُتعلِّقة بواجهة المستخدم فنقترح استخراجها إلى واحدات JavaScript مُنفصِلة، حيث يُمكِن للمُكوِّن أن يستورد ويستخدم الدوال والكائنات والأصناف بدون الحاجة إلى تمديدها عن طريق الكلمة extend
.
انظر أيضًا
- مثال أهلًا بالعالم في React
- مقدمة إلى JSX
- تصيير العناصر
- المكونات والخاصيات
- حالة ودورة حياة المكونات
- معالجة الأحداث في React
- التصيير الشرطي
- القوائم والمفاتيح
- الحقول
- رفع الحالات المشتركة للمستوى الأعلى
- أسلوب التفكير في React