التحديث السريع (Fast Refresh)
التحديث السريع هو ميزة في Next.js تمنحك ملاحظات فورية على التعديلات التي تجريها على مكونات React. التحديث السريع مفعل افتراضيًا في جميع تطبيقات Next.js على الإصدار 9.4 أو الأحدث. مع تفعيل التحديث السريع في Next.js، يجب أن تكون معظم التعديلات مرئية في غضون ثانية، دون فقدان حالة المكون.
كيفية العمل
- إذا قمت بتحرير ملف يصدّر فقط مكون(ات) React، فسيقوم التحديث السريع بتحديث الكود لهذا الملف فقط، وإعادة عرض مكونك. يمكنك تحرير أي شيء في هذا الملف، بما في ذلك الأنماط، منطق العرض، معالجات الأحداث، أو التأثيرات.
- إذا قمت بتحرير ملف يحتوي على تصديرات ليست مكونات React، فسيعيد التحديث السريع تشغيل ذلك الملف والملفات الأخرى التي تستورده. لذا إذا كان كل من
Button.js
وModal.js
يستوردانtheme.js
، فإن تحريرtheme.js
سيحدث كلا المكونين. - أخيرًا، إذا قمت بتحرير ملف يتم استيراده بواسطة ملفات خارج شجرة React، فسيلجأ التحديث السريع إلى إعادة تحميل كاملة. قد يكون لديك ملف يعرض مكون React ولكنه أيضًا يصدر قيمة يتم استيرادها بواسطة مكون غير React. على سبيل المثال، ربما يصدر مكونك أيضًا ثابتًا، ويستورده ملف خدمة غير React. في هذه الحالة، فكر في نقل الثابت إلى ملف منفصل واستيراده في كلا الملفين. هذا سيعيد تفعيل عمل التحديث السريع. يمكن عادةً حل الحالات الأخرى بطريقة مماثلة.
مرونة الأخطاء
أخطاء الصياغة (Syntax Errors)
إذا قمت بخطأ في الصياغة أثناء التطوير، يمكنك إصلاحه وحفظ الملف مرة أخرى. سيختفي الخطأ تلقائيًا، لذا لن تحتاج إلى إعادة تحميل التطبيق. لن تفقد حالة المكون.
أخطاء التشغيل (Runtime Errors)
إذا ارتكبت خطأ يؤدي إلى حدوث خطأ أثناء التشغيل داخل مكونك، فستستقبلك نافذة سياقية. سيؤدي إصلاح الخطأ إلى إغلاق النافذة تلقائيًا دون إعادة تحميل التطبيق.
سيتم الاحتفاظ بحالة المكون إذا لم يحدث الخطأ أثناء العرض. إذا حدث الخطأ أثناء العرض، سيعيد React تحميل تطبيقك باستخدام الكود المحدث.
إذا كان لديك حدود أخطاء (error boundaries) في تطبيقك (وهو أمر جيد لفشل أنيق في الإنتاج)، فستحاول إعادة العرض عند التحرير التالي بعد خطأ في العرض. هذا يعني أن وجود حدود أخطاء يمكن أن يمنعك من العودة دائمًا إلى حالة التطبيق الجذرية. ومع ذلك، تذكر أن حدود الأخطاء لا يجب أن تكون مفرطة في التجزئة. يتم استخدامها بواسطة React في الإنتاج، ويجب دائمًا تصميمها عن قصد.
القيود
يحاول التحديث السريع الحفاظ على حالة React المحلية في المكون الذي تقوم بتحريره، ولكن فقط إذا كان ذلك آمنًا. فيما يلي بعض الأسباب التي قد تجعلك ترى إعادة تعيين الحالة المحلية في كل تحرير للملف:
- لا يتم الحفاظ على الحالة المحلية لمكونات الفئة (فقط مكونات الدالة و Hook تحافظ على الحالة).
- قد يكون الملف الذي تقوم بتحريره يحتوي على تصديرات أخرى بالإضافة إلى مكون React.
- في بعض الأحيان، قد يصدر الملف نتيجة استدعاء مكون ذو ترتيب أعلى مثل
HOC(WrappedComponent)
. إذا كان المكون المرجع فئة، فسيتم إعادة تعيين حالته. - وظائف السهم المجهولة مثل
export default () => <div />;
تسبب عدم حفظ التحديث السريع للحالة المحلية للمكون. بالنسبة لقواعد التعليمات البرمجية الكبيرة، يمكنك استخدام تحويل الكودname-default-component
.
كلما تحولت قاعدة التعليمات البرمجية الخاصة بك إلى مكونات دالة و Hook، يمكنك توقع الحفاظ على الحالة في المزيد من الحالات.
نصائح
- يحفظ التحديث السريع حالة React المحلية في مكونات الدالة (و Hook) افتراضيًا.
- في بعض الأحيان قد ترغب في إجبار إعادة تعيين الحالة، وإعادة تحميل المكون. على سبيل المثال، قد يكون هذا مفيدًا إذا كنت تضبط حركة تحدث فقط عند التحميل. للقيام بذلك، يمكنك إضافة
// @refresh reset
في أي مكان في الملف الذي تقوم بتحريره. هذا التوجيه محلي للملف، ويوجه التحديث السريع لإعادة تحميل المكونات المعرفة في ذلك الملف في كل تحرير. - يمكنك وضع
console.log
أوdebugger;
في المكونات التي تقوم بتحريرها أثناء التطوير. - تذكر أن عمليات الاستيراد حساسة لحالة الأحرف. يمكن أن يفشل كل من التحديث السريع والكامل، عندما لا يتطابق الاستيراد مع اسم الملف الفعلي.
على سبيل المثال،
'./header'
مقابل'./Header'
.
التحديث السريع و Hook
عندما يكون ذلك ممكنًا، يحاول التحديث السريع الحفاظ على حالة مكونك بين التعديلات. على وجه الخصوص، تحتفظ useState
و useRef
بقيمها السابقة طالما لم تقم بتغيير وسائطها أو ترتيب استدعاءات Hook.
الـ Hooks ذات التبعيات - مثل useEffect
، useMemo
، و useCallback
- ستقوم دائمًا بالتحديث أثناء التحديث السريع. سيتم تجاهل قائمة التبعيات الخاصة بها أثناء حدوث التحديث السريع.
على سبيل المثال، عند تحرير useMemo(() => x * 2, [x])
إلى useMemo(() => x * 10, [x])
، سيعيد التشغيل حتى لو لم يتغير x
(التبعية). إذا لم يفعل React ذلك، فلن ينعكس تعديلك على الشاشة!
في بعض الأحيان، يمكن أن يؤدي هذا إلى نتائج غير متوقعة. على سبيل المثال، حتى useEffect
مع مصفوفة فارغة من التبعيات ستظل تعيد التشغيل مرة واحدة أثناء التحديث السريع.
ومع ذلك، فإن كتابة كود مرن لإعادة تشغيل useEffect
العرضية هو ممارسة جيدة حتى بدون التحديث السريع. سيجعل من السهل عليك إدخال تبعيات جديدة له لاحقًا وهو مفعل بواسطة وضع React الصارم (React Strict Mode)، والذي نوصي بشدة بتفعيله.