الفرق بين المراجعتين ل"React/forwarding refs"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
سطر 18: سطر 18:
 
تمرير المراجع هو عبارة عن ميزة تسمح لبعض المكوّنات باستقبال مرجع <code>ref</code> وتمريره إلى المستويات الأدنى إلى المكوّنات الأبناء.
 
تمرير المراجع هو عبارة عن ميزة تسمح لبعض المكوّنات باستقبال مرجع <code>ref</code> وتمريره إلى المستويات الأدنى إلى المكوّنات الأبناء.
  
يستخدم المكوّن <code>FancyButton</code> في المثال التالي <code>React.forwardRef</code> للحصول على المرجع <code>ref</code> المُمرَّر له، ومن ثمّ يُمرِّره إلى الزر <code>button</code> الذي يُصيِّره:
+
يستخدم المكوّن <code>FancyButton</code> في المثال التالي <code>React.forwardRef</code> للحصول على المرجع <code>ref</code> المُمرَّر له، ومن ثمّ يُمرِّره إلى الزر <code>button</code> الذي يُصيِّره:<syntaxhighlight lang="javascript">
 +
const FancyButton = React.forwardRef((props, ref) => (
 +
  <button ref={ref} className="FancyButton">
 +
    {props.children}
 +
  </button>
 +
));
 +
 
 +
// تستطيع الآن الحصول على مرجع بشكل مباشر للزر button
 +
const ref = React.createRef();
 +
<FancyButton ref={ref}>Click me!</FancyButton>;
 +
 
 +
</syntaxhighlight>بهذه الطريقة تستطيع المكوّنات التي تستخدم المكوّن <code>FancyButton</code> الحصول على مرجع للزر <code>button</code> والوصول إليه عند الضرورة كما لو أنّها تستخدم الزر بشكل مباشر.
 +
 
 +
وهذا شرح مُفصَّل عمّا حدث في المثال السابق:
 +
# أنشأنا مرجع <code>ref</code> عن طريق استدعاء <code>React.createRef</code> وتعيينه إلى المتغيّر ref.
 +
# مرّرنا المرجع <code>ref</code> إلى المكوّن ‎<code><FancyButton ref={ref}></code>‎ عن طريق تحديده كخاصيّة JSX.
 +
# تُمرِّر React المرجع <code>ref</code> إلى الدالة <code>‎(props, ref) => ...</code>‎ الموجودة بداخل التابع <code>forwardRef</code> كوسيط ثانٍ له.
 +
# نُمرِّر هذا المرجع إلى الزر <code>‎‎<button ref={ref}></code>‎‎ عن طريق تحديده كخاصيّة JSX.
 +
# عند ربط المرجع <code>ref</code> ستُشير <code>ref.current</code> إلى عقدة DOM الخاصّة بالزر <code>‎<button></code>‎.
 +
'''ملاحظة:''' يُوجَد الوسيط الثاني <code>ref</code> فقط عندما تُعرِّف مكوّن باستخدام الاستدعاء <code>React.forwardRef</code>. لا تستقبل مكوّنات الأصناف أو الدوال الاعتيادية الوسيط <code>ref</code>، وهو ليس متوفر ضمن الخاصيّات حتى.
 +
 
 +
لا يكون تمرير المراجع محدودًا فقط لمكوّنات DOM، فبإمكانك تمرير المراجع إلى نُسَخ مكوّنات الأصناف أيضًا.
 +
 
 +
== ملاحظة بالنسبة لمكتبات المكونات ==
 +
عندما تبدأ باستخدام <code>forwardRef</code> في مكتبة مكوّناتك الخاصّة، فيجب عليك معاملتها كتغيير جذري وإصدار رئيسي جديد من مكتبتك، وذلك لأنّه من الغالب أنّ مكتبتك لديها سلوك ملحوظ مختلف تمامًا (مثل الأشياء التي نُعيِّن إليها المراجع، والأنواع المستخرجة) وقد يُعطِّل هذا التطبيقات والمكتبات الأخرى التي تعتمد على السلوك القديم.
 +
 
 +
لا نوصي بتطبيق <code>React.forwardRef</code> بشكلٍ شرطي عند وجودها لنفس الأسباب، فهي تغيّر سلوك مكتبتك وقد تُعطِّل تطبيقات مستخدميك عند تحديثهم لمكتبة React بحد ذاتها.
 +
 
 +
== تمرير المراجع في المكونات ذات الترتيب الأعلى ==
 +
تكون هذه الطريقة مفيدة بشكل خاص مع المكوّنات ذات الترتيب الأعلى (higher-order components واختصارًا HOCs). فلنبدأ بمثال عن المكوّنات ذات الترتيب الأعلى والذي يعرض خاصيّات المكوّنات في الكونسول:

مراجعة 10:47، 24 أغسطس 2018

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

تمرير المراجع إلى مكونات DOM

فلنأخذ مثال عن المكوّن FancyButton والذي يُصيِّر زر button في DOM:

function FancyButton(props) {
  return (
    <button className="FancyButton">
      {props.children}
    </button>
  );
}

تُخفي مكوّنات React تفاصيلها التنفيذية، بما في ذلك الناتج المُصيَّر. لا تحتاج المكوّنات الأخرى التي تستخدم المكوّن FancyButton عادةً إلى الحصول على مرجع ref لعنصر الزر button الداخلي. يكون هذا جيّدًا لأنّه يمنع المكوّنات من الاعتماد كثيرًا على بنية DOM للمكوّنات الأخرى.

قد يكون مثل هذا التغليف مرغوبًا في مكوّنات التطبيق مثل FeedStory أو Comment، ولكنّه قد يكون غير ملائم بالنسبة للمكوّنات القابلة لإعادة الاستخدام بكثرة مثل FancyButton أو MyTextInput. تميل هذه المكوّنات لاستخدامها عبر التطبيق بنفس الطريقة مثل الزر button وحقل الإدخال input في DOM، وقد يكون الوصول إلى عقد DOM الخاصّة بها أمرًا لا بُدّ منه لإدارة التركيز، أو الاختيار، أو التحريكات.

تمرير المراجع هو عبارة عن ميزة تسمح لبعض المكوّنات باستقبال مرجع ref وتمريره إلى المستويات الأدنى إلى المكوّنات الأبناء.

يستخدم المكوّن FancyButton في المثال التالي React.forwardRef للحصول على المرجع ref المُمرَّر له، ومن ثمّ يُمرِّره إلى الزر button الذي يُصيِّره:

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// تستطيع الآن الحصول على مرجع بشكل مباشر للزر button
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

بهذه الطريقة تستطيع المكوّنات التي تستخدم المكوّن FancyButton الحصول على مرجع للزر button والوصول إليه عند الضرورة كما لو أنّها تستخدم الزر بشكل مباشر.

وهذا شرح مُفصَّل عمّا حدث في المثال السابق:

  1. أنشأنا مرجع ref عن طريق استدعاء React.createRef وتعيينه إلى المتغيّر ref.
  2. مرّرنا المرجع ref إلى المكوّن ‎<FancyButton ref={ref}>‎ عن طريق تحديده كخاصيّة JSX.
  3. تُمرِّر React المرجع ref إلى الدالة ‎(props, ref) => ...‎ الموجودة بداخل التابع forwardRef كوسيط ثانٍ له.
  4. نُمرِّر هذا المرجع إلى الزر ‎‎<button ref={ref}>‎‎ عن طريق تحديده كخاصيّة JSX.
  5. عند ربط المرجع ref ستُشير ref.current إلى عقدة DOM الخاصّة بالزر ‎<button>‎.

ملاحظة: يُوجَد الوسيط الثاني ref فقط عندما تُعرِّف مكوّن باستخدام الاستدعاء React.forwardRef. لا تستقبل مكوّنات الأصناف أو الدوال الاعتيادية الوسيط ref، وهو ليس متوفر ضمن الخاصيّات حتى.

لا يكون تمرير المراجع محدودًا فقط لمكوّنات DOM، فبإمكانك تمرير المراجع إلى نُسَخ مكوّنات الأصناف أيضًا.

ملاحظة بالنسبة لمكتبات المكونات

عندما تبدأ باستخدام forwardRef في مكتبة مكوّناتك الخاصّة، فيجب عليك معاملتها كتغيير جذري وإصدار رئيسي جديد من مكتبتك، وذلك لأنّه من الغالب أنّ مكتبتك لديها سلوك ملحوظ مختلف تمامًا (مثل الأشياء التي نُعيِّن إليها المراجع، والأنواع المستخرجة) وقد يُعطِّل هذا التطبيقات والمكتبات الأخرى التي تعتمد على السلوك القديم.

لا نوصي بتطبيق React.forwardRef بشكلٍ شرطي عند وجودها لنفس الأسباب، فهي تغيّر سلوك مكتبتك وقد تُعطِّل تطبيقات مستخدميك عند تحديثهم لمكتبة React بحد ذاتها.

تمرير المراجع في المكونات ذات الترتيب الأعلى

تكون هذه الطريقة مفيدة بشكل خاص مع المكوّنات ذات الترتيب الأعلى (higher-order components واختصارًا HOCs). فلنبدأ بمثال عن المكوّنات ذات الترتيب الأعلى والذي يعرض خاصيّات المكوّنات في الكونسول: