نقدم لك ترجمة للمقالة التي كتبها Chidume Nnamdi ، والتي تم نشرها على blog.bitsrc.io. إذا كنت تريد معرفة كيفية تجنب التقديم غير الضروري ومدى فائدة الأدوات الجديدة في React ، مرحبًا بك في cat.

يعمل فريق React.js بجد لجعل React يعمل في أسرع وقت ممكن. لتمكين المطورين من تسريع تطبيقات React الخاصة بهم ، تمت إضافة الأدوات التالية إليها:
- React.lazy والتشويق لتأخر تحميل المكون ؛
- مكون نقي
- خطاطيف دورة الحياة يجب أن تكون مكون التحديث (...) {...}.
في هذه المقالة ، سننظر ، من بين أمور أخرى ، في أداة تحسين أخرى تمت إضافتها في React v16.6 لتسريع وظائف المكونات -
React.memo .
نصيحة: استخدم
Bit لتثبيت ومشاركة مكونات React. استخدم مكوناتك لإنشاء تطبيقات جديدة ومشاركتها مع الفريق لتسريع الأمور. جربه!

تقديم إضافي
في React ، يتوافق كل مكون مع وحدة العرض. مكونات لها أيضا الدول. عندما تتغير قيمة الحالة بسبب تصرفات المستخدم ، يدرك المكون أن إعادة الرسم ضرورية. يمكن إعادة رسم مكون التفاعل أي عدد من المرات. في بعض الحالات ، يكون هذا ضروريًا ، ولكن في أغلب الأحيان يمكنك الاستغناء عن عارض ، خاصةً لأنه يبطئ التطبيق إلى حد كبير.
النظر في المكون التالي:
import React from 'react'; class TestC extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } render() { return ( <div > {this.state.count} <button onClick={()=>this.setState({count: 1})}>Click Me</button> </div> ); } } export default TestC;
القيمة الأولية للحالة {count: 0} هي 0. إذا قمت بالنقر فوق الزر Click me ، ستصبح حالة count 1. على الشاشة ، سيتغير 0 أيضًا إلى 1. ولكن إذا نقرنا على الزر مرة أخرى ، فستبدأ المشاكل: لا ينبغي إعادة رسم المكون ، لأنه الشرط لم يتغير. قيمة العداد "إلى" هي 1 ، والقيمة الجديدة هي أيضًا واحدة ، مما يعني أنه ليست هناك حاجة لتحديث DOM.
لرؤية تحديث TestC ، الذي تم فيه ضبط نفس الحالة مرتين ، أضفت طريقتين لدورة الحياة. React يبدأ دورة المكونWillUpdate عندما يتم تحديث / إعادة رسم المكون بسبب تغيير الحالة. تبدأ دورة Reaction componentdidUpdate عندما يتم عرض المكون بنجاح.
إذا أطلقنا المكون في المتصفح وحاولنا النقر فوق الزر "النقر فوقي" عدة مرات ، فسوف نحصل على النتيجة التالية:

يشير تكرار إدخال componentWillUpdate في وحدة التحكم الخاصة بنا إلى أنه يتم إعادة رسم المكون حتى عندما لا تتغير الحالة. هذا هو تقديم إضافي.
المكون النقي / shouldComponentUpdate
سوف يساعدك ربط دورة حياة shouldComponentUpdate على تجنب التقديم غير الضروري في مكونات React.
يقوم
React بتشغيل طريقة
shouldComponentUpdate في بداية تقديم المكون ويتلقى ضوءًا أخضر من هذه الطريقة لمواصلة العملية أو إشارة إلى أن العملية قد تم
تثبيتها .
دعنا ينبغي أن يكون مكوننا تحديث كما يلي:
shouldComponentUpdate(nextProps, nextState) { return true }
nextProps
: قيمة props
التالية التي nextProps
المكون ؛nextState
: قيمة state
التالية التي nextState
المكون.
لذلك نحن نسمح React لتقديم المكون لأن قيمة الإرجاع
true
.
لنفترض أننا نكتب ما يلي:
shouldComponentUpdate(nextProps, nextState) { return false }
في هذه الحالة ، نمنع React لتقديم المكون ، لأنه
false
إرجاع
false
.
مما سبق يتلي ذلك لتقديم المكون الذي نحتاجه للعودة
true
. الآن يمكننا إعادة كتابة مكون TestC كما يلي:
import React from 'react'; class TestC extends React.Component { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } shouldComponentUpdate(nextProps, nextState) { if (this.state.count === nextState.count) { return false } return true } render() { return ( <div> { this.state.count } <button onClick = { () => this.setState({ count: 1 }) }> Click Me </button> </div> ); } } export default TestC;
أضفنا shouldComponentUpdate ربط إلى مكون TestC. الآن
this.state.count
مقارنة قيمة
count
في كائن الحالة الحالية
this.state.count
مع قيمة
count
في كائن الحالة التالي
nextState.count
. إذا كانت متساوية
===
، لا يحدث إعادة الرسم
false
إرجاع
false
. إذا لم تكن متساوية ،
true
إرجاع
true
تشغيل العارض لعرض القيمة الجديدة.
إذا اختبرنا الكود في المتصفح ، فسنرى نتيجة مألوفة:

ولكن من خلال النقر على زر
Click Me
عدة مرات ، كل ما نراه هو ما يلي (يتم عرضه مرة واحدة فقط!):
componentWillUpdate
componentDidUpdate

يمكنك تغيير حالة مكون TestC في علامة التبويب React DevTools. انقر فوق علامة التبويب React ، وحدد TestC على اليمين ، وسترى قيمة حالة العداد:

يمكن تغيير هذه القيمة. انقر فوق النص المضاد واكتب 2 واضغط على Enter.

ستتغير حالة العد ، وسنرى في وحدة التحكم:
componentWillUpdate componentDidUpdate componentWillUpdate componentDidUpdate

كانت القيمة السابقة 1 ، والقيمة الجديدة 2 ، لذلك كانت إعادة الرسم مطلوبة.
دعنا ننتقل إلى
المكون النقي .
ظهر مكون Pure في React في الإصدار v15.5. يتم استخدامه لمقارنة القيم الافتراضية (
change detection
). باستخدام
extend React.PureComponent
، لن تضطر إلى إضافة طريقة دورة حياة
shouldComponentUpdate
للمكونات: يحدث تتبع التغيير بمفرده.
إضافة PureComponent إلى مكون TestC.
import React from 'react'; class TestC extends React.PureComponent { constructor(props) { super(props); this.state = { count: 0 } } componentWillUpdate(nextProps, nextState) { console.log('componentWillUpdate') } componentDidUpdate(prevProps, prevState) { console.log('componentDidUpdate') } render() { return ( <div> { this.state.count } <button onClick = { () => this.setState({ count: 1 }) }> Click Me </button> </div > ); } } export default TestC;
كما ترون ،
shouldComponentUpdate
في تعليق. لم نعد بحاجة لذلك: يتم تنفيذ كل العمل بواسطة
React.PureComponent
.
عند إعادة تشغيل المتصفح لاختبار الحل الجديد ، والنقر على زر
Click Me
عدة مرات ، نحصل على:


كما ترون ، ظهر
component*Update
واحد فقط
component*Update
إدخال
component*Update
في وحدة التحكم.
بعد معرفة كيفية العمل في React مع إعادة الرسم في فئات المكونات من ES6 ، ننتقل إلى وظائف المكون. كيف نحقق نفس النتائج معهم؟
مكونات الوظيفة
نحن نعلم بالفعل كيفية تحسين العمل مع الفئات باستخدام Pure Component
shouldComponentUpdate
دورة حياة
shouldComponentUpdate
. لا أحد يجادل بأن مكونات الفصل هي المكونات الرئيسية لـ React ، لكن يمكنك استخدام الوظائف كمكونات.
function TestC(props) { return ( <div> I am a functional component </div> ) }
من المهم أن تتذكر أن مكونات الوظيفة ، بخلاف مكونات الفئة ، ليس لها أي حالة (على الرغم من أنه قد تم الآن
useState
خطاطيف
useState
، يمكن مناقشة ذلك) ، مما يعني أنه لا يمكننا تكوين إعادة رسمها. أساليب دورة الحياة التي استخدمناها أثناء العمل مع الفصول الدراسية ليست متاحة لنا هنا. إذا تمكنا من إضافة خطافات دورة الحياة إلى مكونات الوظيفة ، فيمكننا إضافة طريقة
shouldComponentUpdate
بأن هناك حاجة إلى أداة تقديم وظيفة. (ربما ارتكب المؤلف خطأً واقعياً في الجملة الأخيرة. - تقريبًا.) وبالطبع ، لا يمكننا استخدام
extend React.PureComponent
.
نحول فئة المكون ES6 TestC إلى دالة مكون.
import React from 'react'; const TestC = (props) => { console.log(`Rendering TestC :` props) return ( <div> {props.count} </div> ) } export default TestC;
بعد التقديم في وحدة التحكم ، نرى
Rendering TestC :5
.

افتح DevTools وانقر فوق علامة التبويب React. سنحاول هنا تغيير قيمة خصائص مكون TestC. حدد TestC ، وسيتم فتح خصائص العداد مع جميع خصائص وقيم TestC على اليمين. نرى فقط العداد مع القيمة الحالية 5.
انقر على الرقم 5 لتغيير القيمة. ستظهر نافذة إدخال بدلاً من ذلك.

إذا قمنا بتغيير القيمة العددية واضغطنا على Enter ، فستتغير خصائص المكون وفقًا للقيمة التي أدخلناها. افترض في 45.

انتقل إلى علامة التبويب وحدة التحكم.

تم إعادة رسم مكون TestC لأن القيمة السابقة 5 قد تغيرت إلى القيمة الحالية - 45. عد إلى علامة التبويب React وقم بتغيير القيمة إلى 45 ، ثم عد إلى وحدة التحكم.

كما ترون ، يتم إعادة رسم المكون مرة أخرى ، على الرغم من أن القيم السابقة والجديدة هي نفسها. :(
كيفية إدارة العارض؟
الحل: React.memo ()
React.memo()
هي ميزة جديدة مقدمة في React v16.6. يشبه مبدأ التشغيل الخاص به مبدأ
React.PureComponent
: المساعدة في إدارة إعادة رسم وظائف المكون.
React.memo(...)
لمكونات الفئة هو
React.PureComponent
لمكونات الوظيفة.
كيفية العمل مع React.memo (...)؟بسيط جدا. قل لدينا وظيفة مكون.
const Funcomponent = ()=> { return ( <div> Hiya!! I am a Funtional component </div> ) }
نحتاج فقط إلى تمرير FuncComponent كوسيطة إلى الدالة React.memo.
const Funcomponent = ()=> { return ( <div> Hiya!! I am a Funtional component </div> ) } const MemodFuncComponent = React.memo(FunComponent)
React.memo إرجاع MemodFuncComponent
purified MemodFuncComponent
. هذا هو ما سنرسمه في JSX العلامات. عندما تتغير خصائص وحالة المكون ، يقارن React الخصائص السابقة والحالية وحالة المكون. وفقط إذا لم تكن متطابقة ، يتم إعادة رسم وظيفة المكون.
قم بتطبيق هذا على مكون وظيفة TestC.
let TestC = (props) => { console.log('Rendering TestC :', props) return ( <div> { props.count } </> ) } TestC = React.memo(TestC);
افتح متصفحًا وقم بتنزيل التطبيق. افتح DevTools وانتقل إلى علامة التبويب React. حدد
<Memo(TestC)>
.
إذا قمنا في المربع الموجود على اليمين بتغيير خصائص العداد إلى 89 ، فسيتم إعادة رسم التطبيق.

إذا قمنا بتغيير القيمة إلى القيمة السابقة ، 89 ، ثم ...

لن يكون هناك إعادة رسم!
المجد ل React.memo (...)! :)
بدون استخدام
React.memo(...)
في المثال الأول لدينا ، يتم إعادة رسم وظيفة مكون TestC حتى عندما تتغير القيمة السابقة إلى القيمة المماثلة. الآن ، بفضل
React.memo(...)
، يمكننا تجنب العرض غير الضروري لوظائف المكون.
استنتاج
- دعنا نذهب من خلال القائمة؟
React.PureComponent
- الفضة.React.memo(...)
- الذهب ؛React.PureComponent
يعمل مع فئات ES6.React.memo(...)
يعمل مع وظائف؛React.PureComponent
يحسن إعادة رسم الطبقات ES6 ؛React.memo(...)
يحسن إعادة رسم الوظيفة ؛- تحسين ميزة هي فكرة رائعة.
React
لن يكون هو نفسه مرة أخرى.
إذا كانت لديك أي أسئلة حول المقالة أو أي معلومات أو تغييرات أو اعتراضات إضافية ، فلا تتردد في كتابة تعليقاتي أو رسائل البريد الإلكتروني أو الرسائل الخاصة.
شكرا لك