الفرق بين المراجعتين لصفحة: «React/react without es6»
Kinan-mawed (نقاش | مساهمات) لا ملخص تعديل |
تحديث |
||
(7 مراجعات متوسطة بواسطة 3 مستخدمين غير معروضة) | |||
سطر 11: | سطر 11: | ||
var Greeting = createReactClass({ | var Greeting = createReactClass({ | ||
render: function() { | render: function() { | ||
return <h1> | return <h1>Hello, {this.props.name}</h1>; | ||
} | } | ||
}); | }); | ||
</syntaxhighlight>تُشبِه واجهة برمجة التطبيقات لأصناف ES6 الصنف <code>createReactClass()</code> مع بعض الاستثناءات. | </syntaxhighlight>تُشبِه واجهة برمجة التطبيقات لأصناف ES6 الصنف <code>createReactClass()</code> مع بعض الاستثناءات. | ||
سطر 60: | سطر 59: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== الربط التلقائي == | |||
تتبع التوابع في مكوّنات React المُعرَّفة كأصناف ES6 نفس القواعد في أصناف ES6 الاعتيادية. يعني هذا أنّها لا تربط <code>this</code> بنسخة الكائن، بل يجب عليك أن تستخدم بشكل صريح التابع <code>.bind(this)</code> في الدالة البانية:<syntaxhighlight lang="javascript"> | |||
class SayHello extends React.Component { | |||
constructor(props) { | |||
super(props); | |||
this.state = {message: 'مرحبًا'}; | |||
// هذا السطر هام | |||
this.handleClick = this.handleClick.bind(this); | |||
} | |||
handleClick() { | |||
alert(this.state.message); | |||
} | |||
render() { | |||
// بما أن this.handleClick مربوط، فنستطيع استخدامه كمعالج للأحداث | |||
return ( | |||
<button onClick={this.handleClick}> | |||
قل مرحبًا | |||
</button> | |||
); | |||
} | |||
} | |||
</syntaxhighlight>لا يكون هذا ضروريًّا مع <code>createReactClass()</code> لأنّها تربط كل التوابع بشكلٍ تلقائي:<syntaxhighlight lang="javascript"> | |||
var SayHello = createReactClass({ | |||
getInitialState: function() { | |||
return {message: 'مرحبًا'}; | |||
}, | |||
handleClick: function() { | |||
alert(this.state.message); | |||
}, | |||
render: function() { | |||
return ( | |||
<button onClick={this.handleClick}> | |||
قل مرحبًا | |||
</button> | |||
); | |||
} | |||
}); | |||
</syntaxhighlight>يعني هذا أن كتابة أصناف ES6 يحتاج لكتابة شيفرة متكررة من أجل معالجات الأحداث ولكنّ الجانب الجيد هنا هو الحصول على أداء أفضل قليلًا في التطبيقات الكبيرة. | |||
إن لم تكرار كتابة الشيفرة فتستطيع تمكين صياغة [https://babeljs.io/docs/plugins/transform-class-properties/ خاصيّات الأصناف] التجريبية مع Babel:<syntaxhighlight lang="javascript"> | |||
class SayHello extends React.Component { | |||
constructor(props) { | |||
super(props); | |||
this.state = {message: 'مرحبًا'}; | |||
} | |||
// تحذير: هذه الصياغة تجريبية | |||
// استخدام السهم هنا يربط التابع | |||
handleClick = () => { | |||
alert(this.state.message); | |||
} | |||
render() { | |||
return ( | |||
<button onClick={this.handleClick}> | |||
مرحبًا | |||
</button> | |||
); | |||
} | |||
} | |||
</syntaxhighlight>انتبه إلى أنّ هذه الصياغة تجريبية وبالتالي قد تتغير أو لا تبقى موجودة أصلًا. | |||
إن كنت تفضّل البقاء بأمان فلديك بعض الخيارات: | |||
* ربط التوابع في الدالة البانية. | |||
* استخدام الدوال السهمية، مثل <code>onClick={(e) => this.handleClick(e)}</code>. | |||
* الاستمرار في استخدام <code>createReactClass</code>. | |||
== المخاليط (Mixins) == | |||
المخاليط هي الأصناف التي تحتوي على دوال متاحة من أجل استخدامها من قبل أصناف أخرى دون أن تكون هذه المخاليط أصنافًا آباء للأصناف التي تحتاجها. | |||
'''ملاحظة:''' أُطلِقت ES6 بدون أي دعم للمخاليط، ولذلك لا يوجد دعم لها عندما تستخدم React مع أصناف ES6. | |||
وجدنا أيضًا العديد من المشاكل عند استخدام المخاليط [https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html ولا نفضّل استخدامها في الشيفرات الجديدة]. | |||
يُوجَد هذا القسم فقط للتوثيق. | |||
قد تتشارك بعض المُكوِّنات المختلفة كثيرًا ببعض الوظائف. يُدعى هذا أحيانًا [[wikipedia:Cross-cutting_concern|بالاهتمامات المشتركة (cross-cutting concerns)]]. يُتيح لك <code>createReactClass</code> أن تستخدم نظام المخاليط القديم لأجل ذلك. | |||
إحدى حالات الاستخدام الشائعة هي عندما يريد المُكوّن تحديث نفسه وفق فاصلة زمنية ثابتة. من السهل استخدام الدالة <code>setInterval()</code> ولكن من الهام أن تلغيها عند عدم الحاجة إليها لتوفير الذاكرة. تُزوِّدنا React [[React/react component|بتوابع دورة حياة المُكوِّنات]] والتي تُعلِمنا بوقت إنشاء أو تدمير المُكوّن. فلنُنشِئ مخلوطًا بسيطًا يستخدم هذه التوابع لإعطائنا دالة <code>setInterval()</code> والتي تتوقف تلقائيًّا عند تدمير المُكوّن:<syntaxhighlight lang="javascript"> | |||
var SetIntervalMixin = { | |||
componentWillMount: function() { | |||
this.intervals = []; | |||
}, | |||
setInterval: function() { | |||
this.intervals.push(setInterval.apply(null, arguments)); | |||
}, | |||
componentWillUnmount: function() { | |||
this.intervals.forEach(clearInterval); | |||
} | |||
}; | |||
var createReactClass = require('create-react-class'); | |||
var TickTock = createReactClass({ | |||
mixins: [SetIntervalMixin], // استخدام المخلوط | |||
getInitialState: function() { | |||
return {seconds: 0}; | |||
}, | |||
componentDidMount: function() { | |||
this.setInterval(this.tick, 1000); // استدعاء تابع على المخلوط | |||
}, | |||
tick: function() { | |||
this.setState({seconds: this.state.seconds + 1}); | |||
}, | |||
render: function() { | |||
return ( | |||
<p> | |||
React قيد التشغيل منذ {this.state.seconds} ثانية. | |||
</p> | |||
); | |||
} | |||
}); | |||
ReactDOM.render( | |||
<TickTock />, | |||
document.getElementById('example') | |||
); | |||
</syntaxhighlight>إذا كان المُكوّن يستخدم مخاليط متعددة تُعرِّف نفس توابع دورة الحياة (أي مثلًا تريد كل هذه المخاليط إيقاف التابع <code>setInterval()</code> عند تدمير المُكوّن)، فسنضمن استدعاء كافة توابع دورة الحياة. تعمل التوابع المُعرَّفة في المخاليط بنفس الترتيب الذي أوردنا فيه هذه المخاليط متبوعةً باستدعاء التابع على المُكوّن. | |||
== انظر أيضًا == | |||
* [[React/jsx in depth|شرح JSX بالتفصيل]] | |||
* [[React/static type checking|التحقق من الأنواع الثابتة]] | |||
* [[React/typechecking with proptypes|التحقق من الأنواع باستخدام PropTypes]] | |||
* [[React/refs and the dom|استخدام المراجع مع DOM]] | |||
* [[React/uncontrolled components|المكونات غير المضبوطة]] | |||
* [[React/optimizing performance|تحسين الأداء]] | |||
* [[React/react without jsx|React بدون JSX]] | |||
* [[React/reconciliation|المطابقة (Reconciliation)]] | |||
* [[React/context|استخدام السياق (Context) في React]] | |||
* [[React/fragments|استخدام الأجزاء (Fragments) في React]] | |||
* [[React/portals|المداخل (Portals) في React]] | |||
* [[React/error boundaries|حدود الأخطاء]] | |||
* [[React/web components|مكونات الويب]] | |||
* [[React/higher order components|المكونات ذات الترتيب الأعلى]] | |||
* [[React/forwarding refs|تمرير المراجع]] | |||
* [[React/render props|خاصيات التصيير]] | |||
* [[React/integrating with other libraries|تكامل React مع المكتبات الأخرى]] | |||
* [[React/accessibility|سهولة الوصول]] | |||
* [[React/code splitting|تقسيم الشيفرة]] | |||
* [[React/strict mode|الوضع الصارم (Strict Mode)]] | |||
== مصادر== | |||
*[https://reactjs.org/docs/react-without-es6.html صفحة React بدون ES6 في توثيق React الرسمي]. | |||
[[تصنيف:React]] | |||
[[تصنيف:React Advanced Guides]] |
المراجعة الحالية بتاريخ 23:38، 3 نوفمبر 2020
نُعرِّف عادةً مُكوّنات React كأصناف JavaScript مُجرَّدة:
class Greeting extends React.Component {
render() {
return <h1>أهلًا {this.props.name}</h1>;
}
}
إن لم تكن تستخدم ES6 بعد، فبإمكانك استخدام الوحدة create-react-class
بدلًا من ذلك:
var createReactClass = require('create-react-class');
var Greeting = createReactClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
تُشبِه واجهة برمجة التطبيقات لأصناف ES6 الصنف createReactClass()
مع بعض الاستثناءات.
تعريف الخاصيات الافتراضية
تُعرَّف الخاصيّات الافتراضيّة defaultProps
في أصناف ودوال ES6 كخاصيّة ضمن المُكوّن نفسه:
class Greeting extends React.Component {
// ...
}
Greeting.defaultProps = {
name: 'Mary'
};
أمّا باستخدام createReactClass()
فتحتاج لتعريف الدالة getDefaultProps()
كدالة ضمن الكائن المُمرَّر:
var Greeting = createReactClass({
getDefaultProps: function() {
return {
name: 'Mary'
};
},
// ...
});
تعيين الحالة المبدئية
في أصناف ES6 تستطيع تعريف الحالة المبدئية عن طريق تعيين this.state
في الدالة البانية:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
// ...
}
يجب عليك مع الدالة createReactClass()
تزويدها بتابع getInitialState
منفصل والذي يُعيد الحالة المبدئية:
var Counter = createReactClass({
getInitialState: function() {
return {count: this.props.initialCount};
},
// ...
});
الربط التلقائي
تتبع التوابع في مكوّنات React المُعرَّفة كأصناف ES6 نفس القواعد في أصناف ES6 الاعتيادية. يعني هذا أنّها لا تربط this
بنسخة الكائن، بل يجب عليك أن تستخدم بشكل صريح التابع .bind(this)
في الدالة البانية:
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'مرحبًا'};
// هذا السطر هام
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
// بما أن this.handleClick مربوط، فنستطيع استخدامه كمعالج للأحداث
return (
<button onClick={this.handleClick}>
قل مرحبًا
</button>
);
}
}
لا يكون هذا ضروريًّا مع createReactClass()
لأنّها تربط كل التوابع بشكلٍ تلقائي:
var SayHello = createReactClass({
getInitialState: function() {
return {message: 'مرحبًا'};
},
handleClick: function() {
alert(this.state.message);
},
render: function() {
return (
<button onClick={this.handleClick}>
قل مرحبًا
</button>
);
}
});
يعني هذا أن كتابة أصناف ES6 يحتاج لكتابة شيفرة متكررة من أجل معالجات الأحداث ولكنّ الجانب الجيد هنا هو الحصول على أداء أفضل قليلًا في التطبيقات الكبيرة. إن لم تكرار كتابة الشيفرة فتستطيع تمكين صياغة خاصيّات الأصناف التجريبية مع Babel:
class SayHello extends React.Component {
constructor(props) {
super(props);
this.state = {message: 'مرحبًا'};
}
// تحذير: هذه الصياغة تجريبية
// استخدام السهم هنا يربط التابع
handleClick = () => {
alert(this.state.message);
}
render() {
return (
<button onClick={this.handleClick}>
مرحبًا
</button>
);
}
}
انتبه إلى أنّ هذه الصياغة تجريبية وبالتالي قد تتغير أو لا تبقى موجودة أصلًا.
إن كنت تفضّل البقاء بأمان فلديك بعض الخيارات:
- ربط التوابع في الدالة البانية.
- استخدام الدوال السهمية، مثل
onClick={(e) => this.handleClick(e)}
. - الاستمرار في استخدام
createReactClass
.
المخاليط (Mixins)
المخاليط هي الأصناف التي تحتوي على دوال متاحة من أجل استخدامها من قبل أصناف أخرى دون أن تكون هذه المخاليط أصنافًا آباء للأصناف التي تحتاجها.
ملاحظة: أُطلِقت ES6 بدون أي دعم للمخاليط، ولذلك لا يوجد دعم لها عندما تستخدم React مع أصناف ES6.
وجدنا أيضًا العديد من المشاكل عند استخدام المخاليط ولا نفضّل استخدامها في الشيفرات الجديدة.
يُوجَد هذا القسم فقط للتوثيق.
قد تتشارك بعض المُكوِّنات المختلفة كثيرًا ببعض الوظائف. يُدعى هذا أحيانًا بالاهتمامات المشتركة (cross-cutting concerns). يُتيح لك createReactClass
أن تستخدم نظام المخاليط القديم لأجل ذلك.
إحدى حالات الاستخدام الشائعة هي عندما يريد المُكوّن تحديث نفسه وفق فاصلة زمنية ثابتة. من السهل استخدام الدالة setInterval()
ولكن من الهام أن تلغيها عند عدم الحاجة إليها لتوفير الذاكرة. تُزوِّدنا React بتوابع دورة حياة المُكوِّنات والتي تُعلِمنا بوقت إنشاء أو تدمير المُكوّن. فلنُنشِئ مخلوطًا بسيطًا يستخدم هذه التوابع لإعطائنا دالة setInterval()
والتي تتوقف تلقائيًّا عند تدمير المُكوّن:
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.forEach(clearInterval);
}
};
var createReactClass = require('create-react-class');
var TickTock = createReactClass({
mixins: [SetIntervalMixin], // استخدام المخلوط
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // استدعاء تابع على المخلوط
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React قيد التشغيل منذ {this.state.seconds} ثانية.
</p>
);
}
});
ReactDOM.render(
<TickTock />,
document.getElementById('example')
);
إذا كان المُكوّن يستخدم مخاليط متعددة تُعرِّف نفس توابع دورة الحياة (أي مثلًا تريد كل هذه المخاليط إيقاف التابع setInterval()
عند تدمير المُكوّن)، فسنضمن استدعاء كافة توابع دورة الحياة. تعمل التوابع المُعرَّفة في المخاليط بنفس الترتيب الذي أوردنا فيه هذه المخاليط متبوعةً باستدعاء التابع على المُكوّن.
انظر أيضًا
- شرح JSX بالتفصيل
- التحقق من الأنواع الثابتة
- التحقق من الأنواع باستخدام PropTypes
- استخدام المراجع مع DOM
- المكونات غير المضبوطة
- تحسين الأداء
- React بدون JSX
- المطابقة (Reconciliation)
- استخدام السياق (Context) في React
- استخدام الأجزاء (Fragments) في React
- المداخل (Portals) في React
- حدود الأخطاء
- مكونات الويب
- المكونات ذات الترتيب الأعلى
- تمرير المراجع
- خاصيات التصيير
- تكامل React مع المكتبات الأخرى
- سهولة الوصول
- تقسيم الشيفرة
- الوضع الصارم (Strict Mode)