الوضع الصارم (Strict Mode) في React

من موسوعة حسوب

الوضع الصارم StrictMode هو عبارة عن أداة لتوضيح المشاكل المحتملة في التطبيق، وهو يُشبِه الأجزاء Fragments في عدم تصييره لأي واجهة مستخدم مرئيّة. يُفعِّل الوضع الصارم تحققات وتحذيرات إضافيّة للمكوّنات المنحدرة عنه.

ملاحظة: يعمل التحقق في الوضع الصارم في وضع التطوير فقط، ولا يؤثر على وضع الإنتاج.

بإمكانك تفعيل الوضع الصارم لأي جزء من تطبيقك، على سبيل المثال:

import React from 'react';

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

في المثال السابق لن يعمل تحقق الوضع الصارم على المكوّنين Header و Footer. سيجري التحقق على المكوّنين ComponentOne و ComponentTwo بالإضافة إلى جميع المكوّنات المنحدرة عنها.

يُساعدنا الوضع الصارم حاليًّا في:

ستُضاف وظائف أخرى في الإصدارات القادمة من React.

التعرف على المكوّنات التي لا تمتلك توابع دورة حياة آمنة

كما هو مشروح في هذا المنشور، من غير الآمن استخدام بعض توابع دورة الحياة القديمة المهملة مع تطبيقات React غير المتزامنة، ولكن إن كان تطبيقك يستخدم مكتبات طرف ثالث فسيصبح من الصعب ضمان عدم استخدام هذه التوابع. لحسن الحظ يُساعدنا الوضع الصارم في كشف ذلك.

عند تمكين الوضع الصارم تُصرِّف React قائمة بالمكوّنات الصنفية التي تستخدم توابع دورة حياة غير آمنة وتُسجِّل رسالة تحذير بمعلومات حول هذه المكوّنات كما يلي:

يؤدّي كشف المشاكل التي يتعرف عليها الوضع الصارم الآن إلى تسهيل استخدامك للتصيير غير المتزامن في إصدارات React القادمة.

التحذير حول استخدام واجهة برمجة التطبيقات (API) القديمة لمراجع السلاسل النصيّة

كانت تزوّدنا React سابقًا بطريقتين لإدارة المراجع، وهما API مراجع السلاسل النصيّة القديمة و API ردود النداء. وعلى الرغم من أنّ الأولى كانت هي الأنسب من بينهما فقد كان لها بعض المشاكل، لذا كانت توصياتنا الرسمية هي استخدام شكل ردود النداء بدلًا منها.

أضاف إصدار React 16.3 خيارًا ثالثًا يوفّر لنا سهولة مراجع السلاسل النصيّة بدون أي مشاكل:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);

    this.inputRef = React.createRef();
  }

  render() {
    return <input type="text" ref={this.inputRef} />;
  }

  componentDidMount() {
    this.inputRef.current.focus();
  }
}

منذ إضافة مراجع الكائنات كبديل لمراجع السلاسل النصيّة أصبح الوضع الصارم يُحذرنا عن استخدام مراجع السلاسل النصيّة.

ملاحظة: سيستمر دعم مراجع ردود النداء بالإضافة إلى createRef API الجديدة.

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

تعلّم المزيد حول createRef من هنا.

التحذير حول استخدام الواجهة findDOMNode المهملة

كانت React تدعم findDOMNode للبحث في الشجرة عن عقدة DOM بإعطاء نسخة صنف. لا تحتاج عادةً إلى ذلك لأنَّك تستطيع ربط مرجعٍ مباشرةً بعقدة DOM.

يمكن استعمال findDOMNode أيضًا مع مكونات الأصناف ولكن عُدَّ ذلك تجاوزًا لمستويات التجريد (abstraction levels) عبر السماح للمكون الأب بطلب ابن محدَّدٍ جرى تصييره. إنَّها تشكل خطرًا بإعادة التصميم في المكان الذي لا يمكنك فيه تغيير تفاصيل التنفيذ لمكونٍ ما؛ سبب ذلك هو أنَّ المكون الأب له قد يكون في قيد الوصول إلى عقدة DOM الخاصة به. تعيد findDOMNode أول مكون ابن فقط ولكن يمكن لأي مكون مع استعمال الأجزاء (Fragments) أن يصيِّر عدة عقد DOM. تعدُّ الواجهة findDOMNode واجهةً برمجيةً تقرأ مرةً واحدةً. أي أنَّها ترد عليك متى ما سألتها فقط. إن صَيَّر عنصرٌ عقدةً مختلفةً، فليس هنالك أي وسيلة لمعالجة هذا التغيير. وبالتالي، تعمل findDOMNode إن أعادت المكونات دومًا عقدة DOM وحيدة لا تتغير على الإطلاق.

يمكنك عوضَ ذلك أن تجعل هذا أكثر وضوحًا عبر تمرير مرجعٍ إلى مكونك المخصص ثم تمريره إلى DOM باستعمال تمرير المراجع.

تستطيع أيضًا إضافة عقدة DOM مغلِّفة في مكونك وربط مرجعٍ بها مباشرةً.

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.wrapper = React.createRef();
  }
  render() {
    return <div ref={this.wrapper}>{this.props.children}</div>;
  }
}`

ملاحظة: في CSS، يمكن استعمال الخاصية display: contents إن لم ترد أن تكون العقدة جزءًا من التخطيط.

كشف التأثيرات الجانبية غير المتوقعة

تعمل React في طورين بشكل نظري:

  • طور التصيير (render) والذي يُحدِّد ما التغييرات التي يجب فعلها (في DOM مثلًا). تستدعي React خلال هذا الطور التابع render ومن ثمّ تُقارِن النتيجة مع التصيير السابق.
  • طور التطبيق (commit) وهو يحدث عند تطبيق React لأي تغييرات (في حالة DOM يحدث عند إدخال وتحديث وإزالة عُقَد DOM). تستدعي React أيضًا توابع دورة الحياة مثل componentDidMount و componentDidUpdate خلال هذا الطور.

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

تتضمّن دورة حياة طور التصيير توابع المكوّنات التالية:

  • constructor.
  • componentWillMount.
  • componentWillReceiveProps.
  • componentWillUpdate.
  • getDerivedStateFromProps.
  • shouldComponentUpdate.
  • render.
  • تابع التحديث setState (الوسيط الأول).

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

لا يستطيع الوضع الصارم كشف الآثار الجانبية تلقائيًّا ولكن يُساعدك على توضيحها عن طريق جعلها أكثر منهجية. يفعل ذلك عن طريق الاستدعاء المزدوج للتوابع التالية عن قصد:

  • التوابع constructor و render و shouldComponentUpdate لمكوّنات الأصناف.
  • التابع الساكنgetDerivedStateFromProps لمكوّنات الأصناف.
  • متون المكونات الدوالية
  • تابع التحديث setState (الوسيط الأول).
  • الدوال المُمرَّرة إلى useState أو useMemo أو useReducer.

ملاحظة: يُطبَّق ذلك في وضع التطوير فقط. لن يحصل الاستدعاء المزدوج في وضع الإنتاج.

على سبيل المثال انظر إلى الشيفرة التالية:

class TopLevelRoute extends React.Component {
  constructor(props) {
    super(props);

    SharedApplicationState.recordEvent('ExampleComponent');
  }
}

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

يتمكن الوضع الصارم عن طريق الاستدعاء المزدوج للتوابع عن قصد مثل الدالة البانية للمكوّن من توضيح مثل هذه المشاكل بشكل أسهل.

كشف واجهة برمجة التطبيقات (API) القديمة للسياق (context)

وهي واجهة مسببة للأخطاء وستُزال بشكل كامل في الإصدار الرئيسي القادم. لا تزال تعمل في الإصدارات 16.x ولكنها ستُظهِر هذه الرسائل التحذيرية في الوضع الصارم:

اقرأ توثيق context API الجديدة ليساعدك على الانتقال إلى الإصدار الجديد.

انظر أيضًا

 مصادر