React/hooks faq
الخطافات هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.
تجيب هذه الصفحة عن بعض الأسئلة التي يتكرر طرحها حول الخطافات.
خطة التبني
أي إصدار من React يتضمن الخطافات؟
بدءًا من الإصدار 16.8.0، تضمنت React تنفيذًا مستقرًا للخطافات من أجل:
- الكائن
ReactDOM
- الكائن
ReactDOMServer
- مصيِّر React السطحي (Shallow Renderer)
ستدعم ReactNative الخطافات دعمًا كاملًا في الإصدار المستقر القادم.
هل احتاج إلى إعادة كتابة جميع مكونات الأصناف الخاصة بي؟
لا. لا يوجد أية خطط مستقبلية لحذف الأصناف من React. ستبقى الأصناف مضمنة في React، إذ لا يمكن تحمُّل إعادة كتابة الشيفرات من جديد. جلَّ ما ننصح به هو تجريب الخطافات في الشيفرات الجديدة.
ما الذي يمكنني فعله مع الخطافات ولا يمكنني فعله مع الأصناف؟
توفر الخطافات وسيلةً جديدةً تتسم بالقوة لإعادة استعمال دالة (وظيفة ما) بين المكونات. توثيق "بناء خطاف خاص بك" يعطيك لمحةً عن ما هو ممكن فعله مع الخطافات. تشرح هذه المقالة الي نشرها أحد أفراد فريق React الأساسيين بنظرة تفصيلية الآفاق التي فُتحَت أمامنا بتوفير الخطافات في React.
ما هي نسبة المعرفة التي بقيت على صلة بـ React فيما يخص الخطافات؟
الخطافات هي طريقة مباشرة لاستعمال ميزات React التي تعرفها مسبقًا مثل الحالة، ودورة الحياة، والسياق، والمراجع (refs). إنها لم تغيِّر بشكل أساسي كيفية عمل Raect، ومعرفتك بالمكونات والخاصيات، وتدفق البيانات من الأعلى إلى الأسفل (top-down data flow) ستبقى كما هي ولن تتغير.
تمتلك الخطافات منحي تعليمي خاص بها فقط. إن كان هنالك أي شيء ناقص في هذا التوثيق، أنشئ مشكلةً على GitHub وسنبذل قصارى جهدنا لمساعدتك.
هل يتوجب علي استعمال الخطافات، أم الأصناف، أو كلاهما؟
نشجع على البدء بتجريب الخطافات واستعمالها في مكوناتك الجديدة عندما تشعر أنك جاهز لذلك. احرص على موافقة كل فرد من أفراد فريقك أيضًا لاستعمالها بعد أن يكونوا قد اطلعوا على كامل توثيق الخطافات. لا ننصح إعادة كتابة الأصناف الموجودة وتحويلها إلى خطافات إلا إذا كنت قد خططت مسبقًا لفعل ذلك (أي لإصلاح مشكلة أو أكثر مثلًا).
لا تستطيع استعمال الخطافات داخل مكون صنف، ولكن يمكنك بالتأكيد المزج بين الأصناف ومكونات دالة مع الخطافات في شجرة واحدة. سواءً كان مكونٌ ما صنفًا أو دالةً، فإن تلك الخطافات المستعملة هي تفاصيل التنفيذ لذلك المكون. نتوقع على المدى البعيد أن تصبح الخطافات الوسيلة الرئيسية التي يستعملها الجميع في كتلة مكونات React.
هل تغطي الخطافات جميع حالات الاستخدام التي توفرها الأصناف؟
هدفنا من الخطافات هو ن تغطي جميع حالات استخدام الأصناف في أقرب وقت ممكن. ليس هنالك أي خطاف مكافئ لدورتي الحياة getSnapshotBeforeUpdate و componentDidCatch الغير شائعتين بعد؛ لا تقلق، إذ سنغطي الخطافات هذه الناحية قريبًا.
ما زالت الخطافات حديثة العهد، وقد لا تتوافق بعض المكتبات الموفرة من طرف ثالث معها في الوقت الحالي.
هل تستبدل الخطافات تصيير الخاصيات والمكونات ذات الترتيب الأعلى؟
غالبًا، خاصيات التصيير والمكونات ذات الترتيب الأعلى تُصيَّر ابنًا واحدًا فقط. نعتقد أنَّ الخطافات هي وسيلة بسيطة لتخدم حالة الاستخدام هذه. لا يزال هنالك متسعٌ لكلا النمطين (قد يملك مكون scroller افتراضي مثلًا الخاصية renderItem أو قد يملك مكون container حاوي على هيكلة DOM خاصة به)؛ ولكن في معظم الحالات، ستكون الخطافات كافية ويمكنها أن تساعد في تقليل التشعب في شجرتك.
ما الذي تعينه الخطافات بالنسبة للواجهات البرمجية الشهيرة مثل connect() في مكتبة Redux ومكتبة React Router؟
يمكنك الاستمرار باستعمال الواجهات البرمجية نفسها التي تستعملها عادةً، إذ ستستمر بالعمل دون أية مشكلات.
في المستقبل، قد تصدر إصدارات جديدة من هاتين المكتبتين خطافات مخصصة مثل useRedux() أو useRouter() تمكنك من استعمال نفس الميزات دون الحاجة إلى مكونات مغلفة.
هل تعمل الخطافات مع أنواع البيانات الثابتة (static typing)؟
صُمِّمَت الخطافات مع أخذ الأنواع الثابتة بالحسبان. لمَّا كانت الخطافات دوالًا، فإنها أسهل للكتابة وبشكل صحيح من أنماط أخرى مثل المكونات ذات المستوى الأعلى. تتضمن أحدث تعريفات للأداة Flow و TypeScript في React دعمًا للخطافات.
الأهم من ذلك أنَّ الخطافات المخصصة تمنحك القوة لتقييد واجهة React البرمجية إن أردت كتابتها بشكل صارم بطريقة ما. توفر لك React الأنواع الأساسية (primitives). ولكن يمكنك الدمج بينها بطرائق عدة أكثر من الطرائق الغير تقليدية التي وفرناها.
كيف يمكن اختبار المكونات التي تستعمل الخطافات؟
من وجهة نظر React، المكونات التي تستعمل الخطافات هي مكونات عادية تمامًا. إن لم يكن خيار الاختبار الخاص بك يعتمد على DOM الافتراضي وكائنات React الداخلية (أي React internals)، يجب ألا تختلف عملية اختبار المكونات مع الخطافات عن تلك التي اعتدت على استعمالها عادةً لاختبار المكونات.
على سبيل المثال، دعنا نفترض أنه لدينا مكون العداد (counter) التالي:
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
سنختبره باستعمال ReactDOM. للتأكد من أن السلوك يتطابق مع ما الذي يحصل في المتصفح، سنغلف عملية تصيير وتحديث الشيفرة في استدعاءات ReactTestUtils.act()
:
import React from 'react';
import ReactDOM from 'react-dom';
import { act } from 'react-dom/test-utils';
import Counter from './Counter';
let container;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null;
});
it('can render and update a counter', () => {
// اختبر أول تصيير وتأثير
act(() => {
ReactDOM.render(<Counter />, container);
});
const button = container.querySelector('button');
const label = container.querySelector('p');
expect(label.textContent).toBe('You clicked 0 times');
expect(document.title).toBe('You clicked 0 times');
// اختبر ثاني تصيير وتأثير
act(() => {
button.dispatchEvent(new MouseEvent('click', {bubbles: true}));
});
expect(label.textContent).toBe('You clicked 1 times');
expect(document.title).toBe('You clicked 1 times');
});
الاستدعاءات act() تطبِّق أيضًا التأثيرات داخلها.
إن أردت اختبار خطاف مخصص، يمكنك فعل ذلك عبر إنشاء مكون في اختبارك، واستعمال ذلك الخطاف منه. وتستطيع بعدئذٍ اختبار المكون الذي كتبته.
لتقليل الشيفرة المتداولة (boilerplate)، نوصي باستعمال المكتبة react-testing-library
التي صُمِّمَت لتشجيع كتابة اختبارات تستعمل مكوناتك كما سيفعل المستخدم النهائي.
ما الذي يحصل بالضبط عند فرض تطبيق قواعد إضافة تصحيح الأخطاء ESLint؟
نوفر الإضافة ESLint التي تفرض تطبيق القواعد الخاصة بالخطافات عليها لتجنب حصول أية أخطاء. إنها تفترض أن أية دالة تبدأ بالسابقة use ثم يليها حرف كبير هي خطاف. نحن ندرك أنَّ هذه الطريقة للتعرف على الخطافات ليست مثالية وقد يكون هنالك بعض الإيجابيات الزائفة (false positives)، ولكن بدون عرف نتشر في بيئة العمل (ecosystem-wide convention)، ليس هنالك أية وسيلة لجعل الخطافات تعمل بشكل صحيح. أضف إلى ذلك أن الأسماء الطويلة ستحبِّط الآخرين من إمَّا تبني الخطافات واستعمالها أو اتباع ما هو متعارف عليه.
باختصار، فرض تطبيق القواعد هي:
- استدعاء الخطافات إمَّا داخل دالة PascalCase (افترض كونها مكونًا) أو دالة useSomething أخرى (افترض كونها خطافًا مخصصًا).
- تُستدعَى الخطافات بالترتيب نفسه في كل عملية تصيير.
هنالك بضعة أساليب كشف (heuristics) أخرى وقد تتغير مع مرور الوقت، إذ نضبط القاعدة ونصيغها لتحقيق التوازن بين إيجاد الأخطاء وتجنب الإيجابيات الزائفة.