الفرق بين المراجعتين لصفحة: «React/hooks intro»

من موسوعة حسوب
تحديث
 
(مراجعة متوسطة واحدة بواسطة مستخدم واحد آخر غير معروضة)
سطر 4: سطر 4:


function Example() {
function Example() {
   // Declare a new state variable, which we'll call "count"
   // "count" التصريح عن متغير حالة جديد سندعوه
   const [count, setCount] = useState(0);
   const [count, setCount] = useState(0);


سطر 20: سطر 20:
هذه الصفحة هي مدخل إلى الخطافات؛ وإذا أردت البدء بتعلم الخطافات، انتقل إلى [[React/hooks overview|الصفحة التالية]]. سنكمل في هذه الصفحة شرح سبب إضافة الخطافات إلى [[React]] وكيف يمكن للخطافات أن تساعدك في كتابة تطبيقات قوية وضخمة.
هذه الصفحة هي مدخل إلى الخطافات؛ وإذا أردت البدء بتعلم الخطافات، انتقل إلى [[React/hooks overview|الصفحة التالية]]. سنكمل في هذه الصفحة شرح سبب إضافة الخطافات إلى [[React]] وكيف يمكن للخطافات أن تساعدك في كتابة تطبيقات قوية وضخمة.


'''ملاحظة''': الإصدار 16.8.0 من [[React]] هو أول إصدار يدعم الخطافات. عند الترقية إليه، لا تنسَ تحديث جميع الحزم بما فيها React DOM. ستدعم [[ReactNative]] الخطافات في الإصدار المستقر القادم.
'''ملاحظة''': الإصدار 16.8.0 من [[React]] هو أول إصدار يدعم الخطافات. عند الترقية إليه، لا تنسَ تحديث جميع الحزم بما فيها React DOM. تدعم [[ReactNative]] الخطافات منذ [https://reactnative.dev/blog/2019/03/12/releasing-react-native-059 الإصدار 0.59].


== ليس هنالك تغييرات مفصلية ==
== ليس هنالك تغييرات كاسرة ==
قبل إكمال القراءة، انتبه إلى أنَّ الخطافات:
قبل إكمال القراءة، انتبه إلى أنَّ الخطافات:
* اختيارية الاستعمال تمامًا. تستطيع تجريب الخطافات ببضعة مكونات دون إعادة كتابة أية شيفرة مكتوبة مسبقًا. مع ذلك، أنت لست مضطرًا لتعلم الخطافات واستعمالها الآن إن لم تكن تريد ذلك أو لست بحاجة إليها في الوقت الحالي.
* اختيارية الاستعمال تمامًا. تستطيع تجريب الخطافات ببضعة مكونات دون إعادة كتابة أية شيفرة مكتوبة مسبقًا. مع ذلك، أنت لست مضطرًا لتعلم الخطافات واستعمالها الآن إن لم تكن تريد ذلك أو لست بحاجة إليها في الوقت الحالي.
* متوافقةٌ مع ما سبقها كليًّا. لا تحوي الخطافات أية تغييرات مفصلية.
* متوافقةٌ مع ما سبقها كليًّا. لا تحوي الخطافات أية تغييرات مفصلية.
* متاحةٌ الآن. أصبحت الخطافات متاحةً الآن بدءًا من الإصدار 16.8.0.
* متاحةٌ الآن. أصبحت الخطافات متاحةً الآن بدءًا من الإصدار 16.8.0.
الجدير بالذكر أنه ليس هنالك أية مخططات لإزالة الأصناف من [[React]]. يمكنك قراءة المزيد حول [[React/hooks intro#.D8.AE.D8.B7.D8.A9 .D8.A7.D9.84.D8.A7.D8.B9.D8.AA.D9.85.D8.A7.D8.AF .D8.A7.D9.84.D8.AA.D8.AF.D8.B1.D9.8A.D8.AC.D9.8A|خطة الاعتماد التدريجي]] للخطافات في الأسفل.
الجدير بالذكر أنَّه ليس هنالك أي خطط لإزالة الأصناف من [[React]]. يمكنك قراءة المزيد حول [[React/hooks intro#.D8.AE.D8.B7.D8.A9 .D8.A7.D9.84.D8.A7.D8.B9.D8.AA.D9.85.D8.A7.D8.AF .D8.A7.D9.84.D8.AA.D8.AF.D8.B1.D9.8A.D8.AC.D9.8A|خطة الاعتماد التدريجي]] للخطافات في الأسفل.


لا تؤثر الخطافات على معرفتك بمفاهيم [[React]]. بدلًا من ذلك، توفر الخطافات أكثر من واجهة برمجية مباشرة (direct API) إلى مفاهيم [[React]] التي تعرفت عليها مسبقًا مثل الخاصيات (props)، والحالة (state)، والسياق (context)، والمراجع (refs)، ودورة الحياة (lifecycle). كما سنشرح لاحقًا، توفر الخطافات أيضًا طريقة جديدة وقوية لدمج المفاهيم مع بعضها.
لا تؤثر الخطافات على معرفتك بمفاهيم [[React]]. بدلًا من ذلك، توفر الخطافات أكثر من واجهة برمجية مباشرة (direct API) إلى مفاهيم [[React]] التي تعرفت عليها مسبقًا مثل الخاصيات (props)، والحالة (state)، والسياق (context)، والمراجع (refs)، ودورة الحياة (lifecycle). كما سنشرح لاحقًا، توفر الخطافات أيضًا طريقة جديدة وقوية لدمج هذه المفاهيم مع بعضها.


إن كنت تود البدء بتعلم الخطافات، يمكنك الانتقال مباشرةً إلى [[React/hooks overview|الصفحة التالية]]. على أي حال، ننصحك بإكمال القراءة إن كنت تريد معرفة سبب إضافة الخطافات وكيفية استخدامها دون إعادة كتابة التطبيقات من جديد.
إن كنت تود البدء بتعلم الخطافات، يمكنك الانتقال مباشرةً إلى [[React/hooks overview|الصفحة التالية]]. على أي حال، ننصحك بإكمال القراءة إن كنت تريد معرفة سبب إضافة الخطافات وكيفية استخدامها دون إعادة كتابة التطبيقات من جديد.
سطر 36: سطر 36:
تحل الخطافات نطاقًا واسعًا من الأخطاء التي تبدو من الظاهر أنها غير مترابطة في [[React]] والتي يمكن أن تواجهها حتى بعد خمس سنوات من كتابة ومراجعة عشرات الآلاف من المكونات. سواءً كنت تتعلم [[React]]، أو تستعلمها يوميًا، أو حتى كنت تفضل استعمال مكتبة أخرى مع نموذج مكونات مشابه، لابد من أن تواجه بعضًا من هذه المشكلات.
تحل الخطافات نطاقًا واسعًا من الأخطاء التي تبدو من الظاهر أنها غير مترابطة في [[React]] والتي يمكن أن تواجهها حتى بعد خمس سنوات من كتابة ومراجعة عشرات الآلاف من المكونات. سواءً كنت تتعلم [[React]]، أو تستعلمها يوميًا، أو حتى كنت تفضل استعمال مكتبة أخرى مع نموذج مكونات مشابه، لابد من أن تواجه بعضًا من هذه المشكلات.


=== من الصعب إعادة استعمال شيفرةٍ ذات حالة بين المكونات ===
=== من الصعب إعادة استعمال شيفرة ذات حالة بين المكونات ===
لا توفر React طريقةً لربط سلوك قابل لإعادة الاستعمال بمكوِّن (مثل ربطه بمتجر). إن كان لديك تجربةً مسبقةً مع React، فقد تكون الأنماط مألوفةً لديك مثل [[React/render props|خاصيات التصيير]] و<nowiki/>[[React/higher order components|المكونات ذات الترتيب الأعلى]] التي تحاول حل هذا الأمر. على أي حال، هذه الأنماط تتطلب منك إعادة هيكلة مكوناتك وجعل الشيفرة صعبة التتبع. إن ألقيت نظرةً على تطبيق React نموذجي في أدوات تطوير React (أي React DevTools)، فستجد غالبًا مغلفًا هائلًا (يدعى "wrapper hell") مُحاطًا بطبقات من المزودين، والمستهلكين، والمكونات ذات الترتيب الأعلى، وخاصيات التصيير، وغيرها. لمَّا كنا نستطيع [https://github.com/facebook/react-devtools/pull/503 ترشيحها في أدوات التطوير]، فهذا يشير إلى مشكلة ضمنية أعمق: تحتاج [[React]] إلى أنواع أساسية أفضل لمشاركة شيفرة ذات حالة (stateful logic).
لا توفر [[React]] طريقةً لربط سلوك قابل لإعادة الاستعمال بمكوِّن (مثل ربطه بمتجر). إن كان لديك تجربةً مسبقةً مع [[React]]، فقد تكون الأنماط مألوفةً لديك مثل [[React/render props|خاصيات التصيير]] و<nowiki/>[[React/higher order components|المكونات ذات الترتيب الأعلى]] التي تحاول حل هذا الأمر. على أي حال، هذه الأنماط تتطلب منك إعادة هيكلة مكوناتك وجعل الشيفرة صعبة التتبع. إن ألقيت نظرةً على تطبيق [[React]] نموذجي في أدوات تطوير [[React]] (أي React DevTools)، فستجد غالبًا مغلفًا هائلًا (يدعى "wrapper hell") مُحاطًا بطبقات من المزودين، والمستهلكين، والمكونات ذات الترتيب الأعلى، وخاصيات التصيير، وغيرها. لمَّا كنا نستطيع [https://github.com/facebook/react-devtools/pull/503 ترشيحها في أدوات التطوير]، فهذا يشير إلى مشكلة ضمنية أعمق: تحتاج [[React]] إلى أنواع أساسية أفضل لمشاركة شيفرة ذات حالة (stateful logic).


باستعمال الخطافات، يمكنك استخراج شيفرة ذات حالة من مكون، وبذلك يمكن التحقق منه بشكل مستقل وإعادة استعماله. تسمح لك الخطافات بإعادة استعمال الشيفرة ذات الحالة دون تغيير هرمية المكونات (component hierarchy). هذا الأمر يجعل من السهل مشاركة الخطافات مع العديد من المكونات أو مع المجتمع نفسه.
باستعمال الخطافات، يمكنك استخراج شيفرة ذات حالة من مكون، وبذلك يمكن التحقق منه بشكل مستقل وإعادة استعماله. تسمح لك الخطافات بإعادة استعمال الشيفرة ذات الحالة دون تغيير هرمية المكونات (component hierarchy). هذا الأمر يجعل من السهل مشاركة الخطافات مع العديد من المكونات أو مع المجتمع نفسه.
سطر 44: سطر 44:


=== المكونات المعقدة تصبح صعبة الفهم ===
=== المكونات المعقدة تصبح صعبة الفهم ===
توجب عليها في كثير من الأحيان صيانة مكونات بدأت بشكل بسيط وما لبثت أن تحولت إلى كتلة من شيفرة ذات حالة يصعب السيطرة عليها مما يولد آثارًا جانبية. تحوي دورة حياة كل تابع غالبًا مزيجًا من الشيفرة عديمة الصلة. على سبيل المثال، قد تنفِّذ المكونات عملية جلب بعض البيانات في <code>componentDidMount</code> و <code>componentDidUpdate</code>. مع ذلك، التابع <code>componentDidMount</code> نفسه قد يحوي أيضًا على بعض الشيفرات عديمة الصلة التي تضبط مستمعات حدث مع عملية تنظيف نُفذِّت في <code>componentWillUnmount</code>. الشيفرة المترابطة بشكل وثيق التي تغير كلاهما تنقسم إلى جزأين ولكن الشيفرة الغير مترابطة على الاطلاق ينتهي بها المطاف بالدمج في تابع واحد. هذا يسهِّل تولّد الأخطاء واجتماع التناقضات.
يتوجب علينا في كثير من الأحيان صيانة مكونات بدأت بشكل بسيط وما لبثت أن تحولت إلى كتلة من شيفرة ذات حالة يصعب السيطرة عليها مما يولد آثارًا جانبية. تحوي دورة حياة كل تابع غالبًا مزيجًا من الشيفرة عديمة الصلة. على سبيل المثال، قد تنفِّذ المكونات عملية جلب بعض البيانات في <code>componentDidMount</code> و <code>componentDidUpdate</code>. مع ذلك، التابع <code>componentDidMount</code> نفسه قد يحوي أيضًا على بعض الشيفرات عديمة الصلة التي تضبط مستمعات حدث مع عملية تنظيف نُفذِّت في <code>componentWillUnmount</code>. الشيفرة المترابطة بشكل وثيق التي تغير كلاهما تنقسم إلى جزأين ولكن الشيفرة الغير مترابطة على الاطلاق ينتهي بها المطاف بالدمج في تابع واحد. هذا يسهِّل تولّد الأخطاء واجتماع التناقضات.


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


لحل هذا الأمر، تسمح لك الخطافات بفصل مكون واحد إلى دوال أصغر بناءً على ترابط الأجزاء مع بعضها بعضًا (مثل إعداد اشتراك أو جلب بيانات) عوضًا عن إجبار الفصل استنادًا إلى توابع دورة الحياة. قد تختار أيضًا إدارة حالة المكونات المحلية مع مخفِّض (reducer) لجعلها أكثر قابلية للتنبؤ.
لحل هذا الأمر، تسمح لك الخطافات بفصل مكون واحد إلى دوال أصغر بناءً على ترابط الأجزاء مع بعضها بعضًا (مثل إعداد اشتراك أو جلب بيانات) عوضًا عن إجبار الفصل استنادًا إلى توابع دورة الحياة. قد تختار أيضًا إدارة حالة المكونات المحلية مع مخفِّض (reducer) لجعلها أكثر قابلية للتنبؤ.
سطر 53: سطر 53:


=== خلط الأصناف بين الأشخاص والأجهزة ===
=== خلط الأصناف بين الأشخاص والأجهزة ===
إضافةً إلى جعل إعادة استعمال الشيفرة وتنظيمها مهمةً صعبةً، وجدنا أنَّ الأصناف يمكن أن تكون  عائقًا كبيرًا لتعلم [[React]]. عليك أن تفهم كيفية عمل <code>this</code> في جافاسكربت، والتي تختلف عن عملها في أغلب اللغات. عليك أيضًا أن تتذكر أن تربط معالجات الحدث. بدون اقتراحات الصيغة، تكون الشيفرة مسهبةً جدًا. يستطيع الآخرون فهم الخاصيات، والحالة، وتدفق البيانات من الأعلى للأسفل بشكل جيد ولكنهم لا يزالون يعانون مع الأصناف. يؤدي الفرق بين مكونات دالة وصنف في [[React]] ومتى يستخدم أحدهما إلى خلافات حتى بين مطوري [[React]] المحنَّكين.
إضافةً إلى جعل إعادة استعمال الشيفرة وتنظيمها مهمةً صعبةً، وجدنا أنَّ الأصناف يمكن أن تشكل عائقًا كبيرًا لتعلم [[React]]. عليك أن تفهم كيفية عمل <code>this</code> في [[JavaScript]]، والتي تختلف عن عملها في أغلب اللغات. عليك أيضًا أن تتذكر أن تربط معالجات الحدث. بدون اقتراحات الصيغة، تكون الشيفرة مسهبةً جدًا. يستطيع الآخرون فهم الخاصيات، والحالة، وتدفق البيانات من الأعلى للأسفل بشكل جيد ولكنهم لا يزالون يعانون مع الأصناف. يؤدي الفرق بين مكونات دالة وصنف في [[React]] ومتى يستخدم أحدهما إلى خلافات حتى بين مطوري [[React]] المحنكين.


إضافة لما سبق، لقد كانت [[React]] متحجِّرة لخمس سنوات ونريد أن نتأكد الآن من بقائها محدَّثة ومُطوَّرة في السنوات الخمس القادمة. كما أظهرت [https://svelte.technology/ Svelte]، و [https://angular.io/ Angular]، و [https://glimmerjs.com/ Glimmer] وغيرها، يملك التصريف المسبق ([[wikipedia:Ahead-of-time_compilation|ahead-of-time compilation]]) للعناصر الكثير من الإمكانيات المستقبلية خصوصًا إن لم تكن محدودة بقالب. مؤخرًا، كنا نجري تجاربًا حول [https://github.com/facebook/react/issues/7323 طي المكونات] باستعمال [https://prepack.io/ Prepack]، وظهرت معنا نتائج واعدة مبكرة. على أي حال، وجدنا أن مكونات الأصناف يمكن أن تدعم الأنماط غير المقصودة (unintentional patterns) التي تجعل هذه التحسينات ترجع إلى مسارٍ أبطأ. تقدم الأصناف مشكلات للأدوات في هذه الأيام أيضًا. على سبيل المثال، الأصناف لا تصغر (minify) بشكل جيد، وتجعل إعادة التحميل الساخن هشًّا وغير موثوق. نريد أن نوجد واجهة برمجية تجعل الشيفرات في الطرف القابل للتحسين دومًا.
إضافةً لما سبق، لقد كانت [[React]] متحجِّرةً لخمس سنوات ونريد أن نتأكد الآن من بقائها محدَّثة ومُطوَّرة في السنوات الخمس القادمة. كما أظهرت [https://svelte.technology/ Svelte]، و [https://angular.io/ Angular]، و [https://glimmerjs.com/ Glimmer] وغيرها، يملك التصريف المسبق ([[wikipedia:Ahead-of-time_compilation|ahead-of-time compilation]]) للعناصر الكثير من الإمكانيات المستقبلية خصوصًا إن لم تكن محدودةً بقالب. مؤخرًا، كنا نجري تجاربًا حول [https://github.com/facebook/react/issues/7323 طي المكونات] باستعمال [https://prepack.io/ Prepack]، وظهرت معنا نتائج واعدة مبكرة. على أي حال، وجدنا أنَّ مكونات الأصناف يمكن أن تدعم الأنماط غير المقصودة (unintentional patterns) التي تجعل هذه التحسينات ترجع إلى مسارٍ أبطأ. تقدم الأصناف مشكلات للأدوات في هذه الأيام أيضًا. على سبيل المثال، الأصناف لا تصغر (minify) بشكل جيد، وتجعل إعادة التحميل الساخن هشًّا وغير موثوق. نريد أن نوجد واجهة برمجية تجعل الشيفرات في الطرف القابل للتحسين دومًا.


لحل هذه المشكلات، تسمح لك الخطافات باستعمال أكثر من ميزة من ميزات [[React]] دون اللجوء إلى الأصناف. من الناحية النظرية، مكونات [[React]] كانت وما تزال أقرب إلى الدوال. الخطافات تتبنى الدوال ولكن بدون التفريط بالجانب العملي في [[React]]. توفر الخطافات الوصول إلى مخارج هروب أمرية (imperative escape hatches) بديلة عن عالم React الوظيفي، إذ لا تطلب منك تعلم تقنيات البرمجة الوظيفية أو التفاعلية المعقدة.
لحل هذه المشكلات، تسمح لك الخطافات باستعمال أكثر من ميزة من ميزات [[React]] دون اللجوء إلى الأصناف. من الناحية النظرية، مكونات [[React]] كانت وما تزال أقرب إلى الدوال. الخطافات تتبنى الدوال ولكن بدون التفريط بالجانب العملي في [[React]]. توفر الخطافات الوصول إلى مخارج هروب أمرية (imperative escape hatches) بديلة عن عالم [[React]] الوظيفي، إذ لا تطلب منك تعلم تقنيات البرمجة الوظيفية أو التفاعلية المعقدة.


=== أمثلة ===
=== أمثلة ===
سطر 65: سطر 65:
نعود ونذكر أنه لا توجد أية نية لحذف الأصناف من [[React]].
نعود ونذكر أنه لا توجد أية نية لحذف الأصناف من [[React]].


نعلم أن مطوري [[React]] يركزون على تضمين المنتجات ولا يملكون الوقت للنظر في كل واجهة برمجية يجري إصدارها. الخطافات جديدةٌ للغاية، ومن الأفضل التريث قليلًا ريثما يتوافر مزيدًا من الأمثلة والدروس التعليمية قبل اتخاذ قرار لتعلمها أو اعتمادها.
نعلم أن مطوري [[React]] يركزون على تضمين المنتجات ولا يملكون الوقت للنظر في كل واجهة برمجية يجري إصدارها. الخطافات جديدةٌ للغاية، ومن الأفضل التريث قليلًا ريثما يتوافر مزيدًا من الأمثلة والدروس التعليمية قبل اتخاذ قرار تعلمها أو اعتمادها.


نتفهَّم أيضًا أنَّ مجال الطلب على إضافة أنواع أساسية جديدة إلى [[React]] مرتفعٌ نسبيًا. للقرَّاء الفضوليين، أعددنا [https://github.com/reactjs/rfcs/pull/68 الدليل RFC المفصل] الذي يتعمق حول دافع إضافة الخطافات، ويوفر نظرة موسعة حول قرارات التصميم المحددة والأسلوب المرتبط السابق.
نتفهَّم أيضًا أنَّ مجال الطلب على إضافة أنواع أساسية جديدة إلى [[React]] مرتفعٌ نسبيًا. للقرَّاء الفضوليين، أعددنا [https://github.com/reactjs/rfcs/pull/68 الدليل RFC المفصل] الذي يتعمق حول دافع إضافة الخطافات، ويوفر نظرة موسعة حول قرارات التصميم المحددة والأسلوب المرتبط السابق.
سطر 71: سطر 71:
الأهم من ذلك، تعمل الخطافات جنبًا بجنب مع الشيفرة القائمة، لذلك يمكنك اعتمادها تدريجيًا. نشارك الآن الواجهة البرمجية التجريبية للحصول على تغذية راجعة من أولئك المهتمين بتشكيل مستقبل [[React]].
الأهم من ذلك، تعمل الخطافات جنبًا بجنب مع الشيفرة القائمة، لذلك يمكنك اعتمادها تدريجيًا. نشارك الآن الواجهة البرمجية التجريبية للحصول على تغذية راجعة من أولئك المهتمين بتشكيل مستقبل [[React]].


أخيرًا، لا يوجد أي شيء يدفع للهجرة إلى الخطافات. ننصح بتجنب اعتماد الخطافات في المكونات الكبيرة خصوصًا مع مكونات الصنف المعقدة. تتطلب عملية تحول الأنظار إلى الخطافات واستعمالها بعض الوقت. بناءً على خبرتنا، من الأفضل التدرب على استعمال الخطافات من الآن في المكونات الجديدة وغير المهمة، والتأكُّد من أن كل شخص في الفريق يشعر براحة تامة معها. بعد تجريب استعمال الخطافات، لا تتردد [https://github.com/facebook/react/issues/new بإرسال تغذية راجعة لنا] سواءً أكانت إيجايبة أم سلبية.
أخيرًا، لا يوجد أي شيء يدفع للهجرة إلى الخطافات. ننصح بتجنب اعتماد الخطافات في المكونات الكبيرة خصوصًا مع مكونات الصنف المعقدة. تتطلب عملية تحول الأنظار إلى الخطافات واستعمالها بعض الوقت. بناءً على خبرتنا، من الأفضل التدرب على استعمال الخطافات من الآن في المكونات الجديدة وغير المهمة، والتأكُّد من أنَّ كل شخص في الفريق يشعر براحة تامة معها. بعد تجريب استعمال الخطافات، لا تتردد [https://github.com/facebook/react/issues/new بإرسال تغذية راجعة لنا] سواءً أكانت إيجايبة أم سلبية.


بخصوص الخطافات، ننوي بأن تشمل جميع حالات الاستخدام الحالية للأصناف، ولكن سنبقي دعم مكونات الأصناف (class components) في المستقبل. في فيسبوك، لدينا عشرات الآلاف من المكونات المكتوبة كأصناف، ولا نملك - بالتأكيد - أية خطة حاليًا لإعادة كتابتها من جديد.
بخصوص الخطافات، ننوي بأن تشمل جميع حالات الاستخدام الحالية للأصناف، ولكن سنبقي دعم مكونات الأصناف (class components) في المستقبل. في فيسبوك، لدينا عشرات الآلاف من المكونات المكتوبة كأصناف، ولا نملك - بالتأكيد - أية خطة حاليًا لإعادة كتابتها من جديد.
سطر 82: سطر 82:


== انظر أيضًا ==
== انظر أيضًا ==
* مدخل إلى الخطافات (الصفحة الحالية)
* [[React/hooks overview|لمحة خاطفة عن الخطافات]]
* [[React/hooks overview|لمحة خاطفة عن الخطافات]]
* [[React/hooks state|استعمال خطاف الحالة]]
* [[React/hooks state|استعمال خطاف الحالة]]

المراجعة الحالية بتاريخ 10:37، 6 نوفمبر 2020

الخطافات هي إضافة جديدة إلى الإصدار 16.8 في React، إذ تسمح لك باستعمال ميزة الحالة وميزات React الأخرى دون كتابة أي صنف.

import React, { useState } from 'react';

function Example() {
  // "count" التصريح عن متغير حالة جديد سندعوه
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

الدالة useState الجديدة هذه هي أول خطاف (Hook) سنتطرق إليه، ولكن هذا المثال هو مجرد مثال تشويقي! لا تقلق إن لم يكن له أي معنى ولم تفهم منه شيئًا بعد.

هذه الصفحة هي مدخل إلى الخطافات؛ وإذا أردت البدء بتعلم الخطافات، انتقل إلى الصفحة التالية. سنكمل في هذه الصفحة شرح سبب إضافة الخطافات إلى React وكيف يمكن للخطافات أن تساعدك في كتابة تطبيقات قوية وضخمة.

ملاحظة: الإصدار 16.8.0 من React هو أول إصدار يدعم الخطافات. عند الترقية إليه، لا تنسَ تحديث جميع الحزم بما فيها React DOM. تدعم ReactNative الخطافات منذ الإصدار 0.59.

ليس هنالك تغييرات كاسرة

قبل إكمال القراءة، انتبه إلى أنَّ الخطافات:

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

الجدير بالذكر أنَّه ليس هنالك أي خطط لإزالة الأصناف من React. يمكنك قراءة المزيد حول خطة الاعتماد التدريجي للخطافات في الأسفل.

لا تؤثر الخطافات على معرفتك بمفاهيم React. بدلًا من ذلك، توفر الخطافات أكثر من واجهة برمجية مباشرة (direct API) إلى مفاهيم React التي تعرفت عليها مسبقًا مثل الخاصيات (props)، والحالة (state)، والسياق (context)، والمراجع (refs)، ودورة الحياة (lifecycle). كما سنشرح لاحقًا، توفر الخطافات أيضًا طريقة جديدة وقوية لدمج هذه المفاهيم مع بعضها.

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

الحافز لإضافة الخطافات

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

من الصعب إعادة استعمال شيفرة ذات حالة بين المكونات

لا توفر React طريقةً لربط سلوك قابل لإعادة الاستعمال بمكوِّن (مثل ربطه بمتجر). إن كان لديك تجربةً مسبقةً مع React، فقد تكون الأنماط مألوفةً لديك مثل خاصيات التصيير والمكونات ذات الترتيب الأعلى التي تحاول حل هذا الأمر. على أي حال، هذه الأنماط تتطلب منك إعادة هيكلة مكوناتك وجعل الشيفرة صعبة التتبع. إن ألقيت نظرةً على تطبيق React نموذجي في أدوات تطوير React (أي React DevTools)، فستجد غالبًا مغلفًا هائلًا (يدعى "wrapper hell") مُحاطًا بطبقات من المزودين، والمستهلكين، والمكونات ذات الترتيب الأعلى، وخاصيات التصيير، وغيرها. لمَّا كنا نستطيع ترشيحها في أدوات التطوير، فهذا يشير إلى مشكلة ضمنية أعمق: تحتاج React إلى أنواع أساسية أفضل لمشاركة شيفرة ذات حالة (stateful logic).

باستعمال الخطافات، يمكنك استخراج شيفرة ذات حالة من مكون، وبذلك يمكن التحقق منه بشكل مستقل وإعادة استعماله. تسمح لك الخطافات بإعادة استعمال الشيفرة ذات الحالة دون تغيير هرمية المكونات (component hierarchy). هذا الأمر يجعل من السهل مشاركة الخطافات مع العديد من المكونات أو مع المجتمع نفسه.

سنناقش هذا الأمر بمزيد من التفصيل في صفحة "بناء خطاف خاص بك".

المكونات المعقدة تصبح صعبة الفهم

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

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

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

سنناقش هذا الموضوع بتفصيل أوسع في التوثيق "استعمال خطاف التأثير".

خلط الأصناف بين الأشخاص والأجهزة

إضافةً إلى جعل إعادة استعمال الشيفرة وتنظيمها مهمةً صعبةً، وجدنا أنَّ الأصناف يمكن أن تشكل عائقًا كبيرًا لتعلم React. عليك أن تفهم كيفية عمل this في JavaScript، والتي تختلف عن عملها في أغلب اللغات. عليك أيضًا أن تتذكر أن تربط معالجات الحدث. بدون اقتراحات الصيغة، تكون الشيفرة مسهبةً جدًا. يستطيع الآخرون فهم الخاصيات، والحالة، وتدفق البيانات من الأعلى للأسفل بشكل جيد ولكنهم لا يزالون يعانون مع الأصناف. يؤدي الفرق بين مكونات دالة وصنف في React ومتى يستخدم أحدهما إلى خلافات حتى بين مطوري React المحنكين.

إضافةً لما سبق، لقد كانت React متحجِّرةً لخمس سنوات ونريد أن نتأكد الآن من بقائها محدَّثة ومُطوَّرة في السنوات الخمس القادمة. كما أظهرت Svelte، و Angular، و Glimmer وغيرها، يملك التصريف المسبق (ahead-of-time compilation) للعناصر الكثير من الإمكانيات المستقبلية خصوصًا إن لم تكن محدودةً بقالب. مؤخرًا، كنا نجري تجاربًا حول طي المكونات باستعمال Prepack، وظهرت معنا نتائج واعدة مبكرة. على أي حال، وجدنا أنَّ مكونات الأصناف يمكن أن تدعم الأنماط غير المقصودة (unintentional patterns) التي تجعل هذه التحسينات ترجع إلى مسارٍ أبطأ. تقدم الأصناف مشكلات للأدوات في هذه الأيام أيضًا. على سبيل المثال، الأصناف لا تصغر (minify) بشكل جيد، وتجعل إعادة التحميل الساخن هشًّا وغير موثوق. نريد أن نوجد واجهة برمجية تجعل الشيفرات في الطرف القابل للتحسين دومًا.

لحل هذه المشكلات، تسمح لك الخطافات باستعمال أكثر من ميزة من ميزات React دون اللجوء إلى الأصناف. من الناحية النظرية، مكونات React كانت وما تزال أقرب إلى الدوال. الخطافات تتبنى الدوال ولكن بدون التفريط بالجانب العملي في React. توفر الخطافات الوصول إلى مخارج هروب أمرية (imperative escape hatches) بديلة عن عالم React الوظيفي، إذ لا تطلب منك تعلم تقنيات البرمجة الوظيفية أو التفاعلية المعقدة.

أمثلة

توثيق "لمحة خاطفة عن الخطافات" هو المكان الأمثل لبدء تعلم الخطافات، إذ يوفر الكثير من الأمثلة العملية المفيدة.

خطة الاعتماد التدريجي

نعود ونذكر أنه لا توجد أية نية لحذف الأصناف من React.

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

نتفهَّم أيضًا أنَّ مجال الطلب على إضافة أنواع أساسية جديدة إلى React مرتفعٌ نسبيًا. للقرَّاء الفضوليين، أعددنا الدليل RFC المفصل الذي يتعمق حول دافع إضافة الخطافات، ويوفر نظرة موسعة حول قرارات التصميم المحددة والأسلوب المرتبط السابق.

الأهم من ذلك، تعمل الخطافات جنبًا بجنب مع الشيفرة القائمة، لذلك يمكنك اعتمادها تدريجيًا. نشارك الآن الواجهة البرمجية التجريبية للحصول على تغذية راجعة من أولئك المهتمين بتشكيل مستقبل React.

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

بخصوص الخطافات، ننوي بأن تشمل جميع حالات الاستخدام الحالية للأصناف، ولكن سنبقي دعم مكونات الأصناف (class components) في المستقبل. في فيسبوك، لدينا عشرات الآلاف من المكونات المكتوبة كأصناف، ولا نملك - بالتأكيد - أية خطة حاليًا لإعادة كتابتها من جديد.

الأسئلة الشائعة

وفرنا قسمًا خاصًّا للأسئلة الشائعة تجيب عن أغلب الأسئلة الشائعة المتعلقة بالخطافات.

الخطوات التالية

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

انظر أيضًا

مصادر