تكشف المادة ، التي ننشرها اليوم ، عن الأساليب التي يستخدمها مؤلفها عند تنظيم تطبيقات React. على وجه الخصوص ، سنناقش هنا بنية المجلد المستخدمة ، وتسمية الكيانات ، والأماكن التي توجد بها ملفات الاختبار ، وأشياء أخرى مماثلة.
واحدة من أكثر الميزات متعة في React هي أن هذه المكتبة لا تجبر المطور على التقيد الصارم ببعض الاتفاقيات المتعلقة بهيكل المشروع. يبقى الكثير من هذا حسب تقدير المبرمج. يختلف هذا النهج عن ذلك ، على سبيل المثال ، المعتمد في أطر عمل Ember.js أو الزاوي. أنها توفر للمطورين المزيد من الميزات القياسية. هذه الأطر تنص على الاتفاقيات المتعلقة بهيكل المشاريع والقواعد لتسمية الملفات والمكونات.

أنا شخصياً أحب النهج الذي تبناه React. الحقيقة هي أنني أفضل التحكم في شيء بنفسي ، دون الاعتماد على "اتفاقيات" معينة. ومع ذلك ، هناك العديد من المزايا لنهج هيكلة المشاريع التي تقدم Angular. يعود الاختيار بين الحرية والقواعد الصارمة أو أكثر إلى ما هو أقرب إليك وإلى فريقك.
على مدار سنوات العمل مع React ، جربت العديد من الطرق المختلفة لتنظيم التطبيقات. تحولت بعض الأفكار التي تقدمت إليها إلى أنجح من غيرها. لذلك ، سوف أتحدث هنا عن كل ما أظهر نفسه جيدًا في الممارسة. أتمنى أن تجد شيئًا مفيدًا لك هنا.
لا أحاول إظهار طريقة "مناسبة فقط" لهيكلة التطبيقات. يمكنك أن تأخذ بعض أفكاري وتغييرها لتناسب احتياجاتك. قد تختلف معي تمامًا من خلال الاستمرار في العمل كما فعلت من قبل. فرق مختلفة تنشئ تطبيقات مختلفة وتستخدم وسائل مختلفة لتحقيق أهدافها.
من المهم ملاحظة أنه إذا نظرت إلى موقع ويب
Thread ، الذي أشارك فيه في التطوير ، ونظرت إلى جهاز واجهته ، ستجد أماكن لا تحترم فيها تلك القواعد التي سأتحدث عنها. والحقيقة هي أن أي "قواعد" في البرمجة يجب أن تؤخذ فقط كتوصيات ، وليس كمعايير شاملة صالحة في أي موقف. وإذا كنت تعتقد أن نوعًا ما من "القواعد" لا يناسبك - يجب عليك ، من أجل تحسين نوعية ما تعمل عليه ، أن تجد القوة اللازمة للانحراف عن هذه "القواعد".
في الواقع ، الآن ، دون مزيد من اللغط ، أقدم لك قصتي حول هيكلة تطبيقات React.
لا تقلق كثيرا بشأن القواعد.
ربما تقرر أن التوصية بعدم القلق بشأن القواعد تبدو غريبة في بداية حديثنا. ولكن هذا هو بالضبط ما أعنيه عندما أقول أن الخطأ الرئيسي الذي لدى المبرمجين فيما يتعلق بمراعاة القواعد هو أن المبرمجين يولون أهمية كبيرة للقواعد. هذا صحيح بشكل خاص في بداية العمل في مشروع جديد. في وقت إنشاء أول
index.jsx
المستحيل معرفة ما هو الأفضل لهذا المشروع. مع تطور المشروع ، سوف تتوصل بطبيعة الحال إلى نوع من بنية الملفات والمجلدات ، والتي من المحتمل أن تكون جيدة لهذا المشروع. إذا تبين أثناء استمرار العمل أن الهيكل الحالي غير ناجح إلى حد ما ، فيمكن تحسينه.
إذا قرأت هذا ورأت نفسك تفكر في أنه لا يوجد شيء في طلبك قيد المناقشة ، فهذه ليست مشكلة. كل تطبيق فريد من نوعه ، لا يوجد فرق تطوير متطابقة تمامًا. لذلك ، يتوصل كل فريق ، يعمل في مشروع ، إلى بعض الاتفاقات المتعلقة بهيكله وأساليب عمله. هذا يساعد أعضاء الفريق على العمل بشكل منتج. لا تجتهد ، بعد أن تعلمت كيف يفعل شخص ما شيئًا ما ، أدخل هذا على الفور إلى نفسك. لا تحاول أن تقدم في عملك ما يسمى بمواد معينة ، وحتى في هذا ، "الطريقة الأكثر فعالية" لحل المشكلة. لقد التزمت دائمًا بالاستراتيجية التالية المتعلقة بهذه التوصيات والتقيد بها. لديّ مجموعة من القواعد الخاصة بي ، ولكني أقرأ كيف يتصرف الآخرون في مواقف معينة ، اخترت ما يبدو لي ناجحًا ومناسبًا بالنسبة لي. هذا يؤدي إلى حقيقة أنه مع مرور الوقت ، تتحسن طرق عملي. في الوقت نفسه ، ليس لدي أي صدمات وليست هناك رغبة في إعادة كتابة كل شيء من الصفر.
توجد مكونات مهمة في مجلدات منفصلة
تتمثل الطريقة المتبعة لوضع ملفات المكونات في مجلدات في أن المكونات التي يمكن اعتبارها "مهمة" أو "أساسية" أو "أساسية" في سياق التطبيق يتم وضعها في مجلدات منفصلة. هذه المجلدات ، بدورها ، موجودة في مجلد
components
. على سبيل المثال ، إذا كنا نتحدث عن تطبيق لمتجر إلكتروني ، فيمكن عندئذٍ التعرف على مكون
<Product>
المستخدم لوصف المنتج كمكون مماثل. هنا ما أقصده:
- src/ - components/ - product/ - product.jsx - product-price.jsx - navigation/ - navigation.jsx - checkout-flow/ - checkout-flow.jsx
في هذه الحالة ، توجد المكونات "الثانوية" التي تستخدمها فقط بعض المكونات "الرئيسية" في نفس المجلد مثل هذه المكونات "الرئيسية". وقد أثبت هذا النهج نفسه في الممارسة العملية. الحقيقة هي أنه بسبب تطبيقه ، تظهر بنية معينة في المشروع ، لكن مستوى تداخل المجلد ليس كبيرًا جدًا. لا يؤدي تطبيقه إلى ظهور شيء مثل
../../../
في أوامر استيراد المكون ، ولا يجعل من الصعب التنقل حول المشروع. يتيح لك هذا النهج بناء تسلسل هرمي واضح للمكونات. يعتبر هذا المكون ، الذي يتطابق اسمه مع اسم المجلد ، "أساسي". تخدم المكونات الأخرى الموجودة في نفس المجلد الغرض من تقسيم المكون "الأساسي" إلى أجزاء ، مما يبسط العمل مع رمز هذا المكون ودعمه.
على الرغم من أنني مؤيد لوجود بنية مجلد معينة في المشروع ، أعتقد أن الشيء الأكثر أهمية هو اختيار أسماء الملفات الجيدة. المجلدات نفسها أقل أهمية.
باستخدام المجلدات الفرعية للمكونات الفرعية
أحد عيوب النهج أعلاه هو أن استخدامه يمكن أن يؤدي إلى ظهور مجلدات المكونات "الأساسية" التي تحتوي على الكثير من الملفات. النظر ، على سبيل المثال ، المكون
<Product>
. سيتم إرفاق ملفات CSS به (سنتحدث عنها لاحقًا) ، واختبار الملفات ، والعديد من المكونات الفرعية ، وربما موارد أخرى - مثل الصور وأيقونات SVG. قائمة "الإضافات" هذه ليست محدودة. كل هذا سوف يقع في نفس المجلد مثل المكون "الأساسي".
لا يهمني ذلك حقًا. هذا يناسبني إذا كانت الملفات لها أسماء مدروسة جيدًا ، وإذا كان يمكن العثور عليها بسهولة (باستخدام أدوات البحث عن الملفات في المحرر). إذا كان الأمر كذلك ، فإن بنية المجلد تتلاشى في الخلفية.
إليك تغريدة حول هذا الموضوع.
ومع ذلك ، إذا كنت تفضل أن يكون لمشروعك بنية أكثر شمولاً ، فلا يوجد صعوبة في نقل المكونات الفرعية إلى مجلداتهم الخاصة:
- src/ - components/ - product/ - product.jsx - ... - product-price/ - product-price.jsx
توجد ملفات الاختبار في نفس مكان ملفات المكونات قيد الاختبار.
نبدأ هذا القسم بتوصية بسيطة ، وهي أن ملفات الاختبار يجب أن توضع في نفس المكان الذي توجد فيه الملفات التي بها الكود الذي تم التحقق منه بمساعدتها. سأتحدث أيضًا عن الطريقة التي أفضل بها هيكلة المكونات ، مع محاولة التأكد من أنها ستكون قريبة من بعضها البعض. ولكن الآن يمكنني القول أنني أجد أنه من المناسب وضع ملفات الاختبار في نفس المجلدات مثل ملفات المكونات. في هذه الحالة ، تكون أسماء الملفات ذات الاختبارات متطابقة مع أسماء الملفات التي تحتوي على الكود. إلى أسماء الاختبار ، قبل ملحق اسم الملف ،
.test
إضافة اللاحقة. الاختبار فقط:
- اسم ملف المكون:
auth.js
- اسم ملف الاختبار:
auth.test.js
هذا النهج لديه العديد من نقاط القوة:
- يجعل من السهل العثور على ملفات الاختبار. في لمحة ، يمكنك أن تفهم ما إذا كان هناك اختبار للمكون الذي أعمل معه.
- جميع أوامر الاستيراد الضرورية بسيطة للغاية. في الاختبار ، لاستيراد الكود الذي تم اختباره ، لا تحتاج إلى إنشاء هياكل تصف ، على سبيل المثال ، الخروج من مجلد
__tests__
. هذه الفرق تبدو بسيطة للغاية. على سبيل المثال ، مثل هذا: import Auth from './auth'
.
إذا كان لدينا بعض البيانات المستخدمة أثناء الاختبار ، على سبيل المثال ، شيء مثل API طلب يسخر ، نضعها في نفس المجلد حيث يوجد المكون واختباره بالفعل. عندما يكمن كل ما قد يلزم في مجلد واحد ، فإن هذا يساهم في نمو الإنتاجية. على سبيل المثال ، إذا استخدمت بنية مجلد متفرعة وكان المبرمج متأكدًا من وجود ملف معين ، لكن لا يمكنه تذكر اسمه ، فسيتعين على المبرمج البحث عن هذا الملف في العديد من الدلائل الفرعية. باستخدام الطريقة المقترحة ، انظر فقط إلى محتويات مجلد واحد وكل شيء سيصبح واضحًا.
وحدات CSS
أنا معجب كبير
بوحدات CSS . لقد وجدنا أنها رائعة لإنشاء قواعد CSS معيارية للمكونات.
بالإضافة إلى ذلك ، أحب حقًا تكنولوجيا
المكونات المصممة . ومع ذلك ، أثناء العمل على المشاريع التي شارك فيها العديد من المطورين ، اتضح أن وجود ملفات CSS حقيقية في المشروع يزيد من قابليتها للاستخدام.
كما قد تكون خمنت بالفعل ، توجد ملفات CSS لدينا ، مثل الملفات الأخرى ، بجانب ملفات المكونات ، في نفس المجلدات. يعمل ذلك على تبسيط الحركة بين الملفات بشكل كبير عندما تحتاج إلى فهم معنى الفصل الدراسي بسرعة.
هناك توصية أكثر عمومية ، يتخلل جوهرها جميع هذه المواد ، وهي أن جميع الشفرات المتعلقة بمكون معين يجب أن تبقى في نفس المجلد الذي يوجد به هذا المكون. لقد ولت الأيام التي تم فيها استخدام مجلدات منفصلة لتخزين كود CSS و JS ورمز الاختبار وموارد أخرى. يؤدي استخدام هياكل المجلد المعقدة إلى تعقيد الحركة بين الملفات وليس له أي فائدة واضحة ، إلا أنه يساعد على "تنظيم الكود". احتفظ بالملفات المترابطة في نفس المجلد - وهذا يعني قضاء وقت أقل في التنقل بين المجلدات أثناء العمل.
لقد أنشأنا حتى أداة تحميل Webpack لـ CSS ، والتي تتوافق قدراتها مع ميزات عملنا. إنه يتحقق من أسماء الفئات المعلنة ويلقي خطأ في وحدة التحكم إذا أشرنا إلى فئة غير موجودة.
دائمًا ، يتم وضع رمز مكون واحد فقط في ملف واحد
توضح تجربتي أن المبرمجين عادةً ما يلتزمون بشدة بالقاعدة التي مفادها أنه يجب أن يكون رمز مكون واحد ومكون React واحد فقط في ملف واحد. في الوقت نفسه ، أؤيد تمامًا فكرة أنه لا يستحق وضع الكثير من المكونات في ملف واحد (فقط تخيل صعوبات تسمية مثل هذه الملفات!). لكنني أعتقد أنه لا يوجد خطأ في وضع نفس الملف الذي يوجد به رمز مكون "كبير" معين ورمز المكون "الصغير" المرتبط به. إذا كانت هذه الخطوة تساعد في الحفاظ على نقاء الكود ، وإذا كان المكون "الصغير" ليس كبيرًا جدًا لوضعه في ملف منفصل ، فلن يؤذي ذلك أي شخص.
على سبيل المثال ، إذا قمت بإنشاء مكون
<Product>
، وكنت بحاجة إلى جزء صغير من التعليمات البرمجية لعرض السعر ، فيمكنني القيام بذلك:
const Price = ({ price, currency }) => ( <span> {currency} {formatPrice(price)} </span> ) const Product = props => {
الشيء الجيد في هذا الأسلوب هو أنني لم أضطر إلى إنشاء ملف منفصل للمكون
<Price>
، وأن هذا المكون متاح حصريًا للمكون
<Product>
. لا نقوم بتصدير هذا المكون ، لذلك لا يمكن استيراده في مكان آخر في التطبيق. هذا يعني أنه عند سؤالك ما إذا كنت تريد وضع
<Price>
في ملف منفصل ، يمكنك تقديم إجابة واضحة وإيجابية إذا كنت تريد استيراده إلى مكان آخر. خلاف ذلك ، يمكنك الاستغناء عن وضع الكود
<Price>
في ملف منفصل.
مجلدات منفصلة للمكونات العالمية
لقد تم مؤخرا استخدام مكونات عالمية. إنهم ، في الواقع ، يشكلون نظام التصميم الخاص بنا (الذي نعتزم نشره يومًا ما) ، لكننا بدأنا حتى الآن صغيرًا - بمكونات مثل
<Button>
و
<Logo>
. يعتبر المكون "عالميًا" إذا لم يكن مرتبطًا بجزء معين من الموقع ، ولكنه يعد أحد العناصر الأساسية لواجهة المستخدم.
توجد مكونات مماثلة في المجلد الخاص بك (
src/components/generic
). هذا يبسط العمل إلى حد كبير مع جميع المكونات العالمية. هم في مكان واحد - أنها مريحة للغاية. بمرور الوقت ، مع نمو المشروع ، نخطط لتطوير دليل للأسلوب (نحن من المعجبين الكبار بأسلوب دليل
رد الفعل ) من أجل زيادة تبسيط العمل مع المكونات العالمية.
استخدام الأسماء المستعارة لاستيراد الكيانات
تضمن بنية المجلد المسطحة نسبيًا في مشاريعنا أن أوامر الاستيراد لا تحتوي على هياكل طويلة جدًا مثل
../../
. لكن من الصعب الاستغناء عنها. لذلك ، استخدمنا
babel-plugin-module-حلال الحلول لتكوين الأسماء المستعارة التي تبسط أوامر الاستيراد.
يمكنك أن تفعل الشيء نفسه مع Webpack ، ولكن بفضل ملحق Babel ، يمكن أن تعمل أوامر الاستيراد نفسها في الاختبارات.
لقد قمنا بتكوين هذا باستخدام زوج من الأسماء المستعارة:
{ components: './src/components', '^generic/([\\w_]+)': './src/components/generic/\\1/\\1', }
الأول بسيط للغاية. يسمح لك باستيراد أي مكون ، وبدء الأمر باستخدام
components
الكلمة. في الطريقة العادية ، تبدو أوامر الاستيراد بالشكل التالي:
import Product from '../../components/product/product'
بدلاً من ذلك ، يمكننا أن نكتبها هكذا:
import Product from 'components/product/product'
كلا الأمرين استيراد نفس الملف. هذا مريح للغاية ، لأنه يسمح لك بعدم التفكير في بنية المجلد.
الاسم المستعار الثاني أكثر تعقيدًا:
'^generic/([\\w_]+)': './src/components/generic/\\1/\\1',
نحن نستخدم regex هنا. يعثر على أوامر الاستيراد التي تبدأ بـ
generic
(تسمح لك علامة
^
في بداية التعبير بتحديد تلك الأوامر التي تبدأ بـ
generic
) ، وتلتقط ما هو بعد
generic/
في المجموعة. بعد ذلك ، نستخدم الجزء الذي تم التقاطه (
\\1
) في
./src/components/generic/\\1/\\1
.
نتيجة لذلك ، يمكننا استخدام أوامر الاستيراد للمكونات العامة من هذا النوع:
import Button from 'generic/button'
يتم تحويلها إلى الأوامر التالية:
import Button from 'src/components/generic/button/button'
يعمل هذا الأمر ، على سبيل المثال ، على استيراد ملف JSX يصف زرًا عامًا. لقد فعلنا كل هذا لأن هذا النهج يبسط إلى حد كبير استيراد المكونات العالمية. بالإضافة إلى ذلك ، سيكون من المفيد لنا إذا قررنا تغيير هيكل ملفات المشروع (هذا ، مع نمو نظام التصميم لدينا ، أمر ممكن للغاية).
هنا أود أن أشير إلى أنه يجب أن تكون حذراً عند العمل مع الأسماء المستعارة. إذا كان لديك عدد قليل منها ، وتم تصميمها لحل مشكلات الاستيراد القياسية ، فسيكون كل شيء على ما يرام. ولكن إذا كان لديك الكثير منهم ، فيمكنهم إحداث المزيد من الالتباس أكثر من النفع.
المجلد ليب العالمي للأدوات المساعدة
أرغب في استعادة الوقت الذي قضيته في محاولة للعثور على المكان المثالي للرمز الذي لا يمثل رمز المكون. شاركت كل هذا وفقًا لمبادئ مختلفة ، مع التركيز على رمز المرافق والخدمات والوظائف الإضافية. كل هذا له العديد من الأسماء التي لم أذكرها جميعًا. الآن لا أحاول معرفة الفرق بين "الأداة المساعدة" و "الوظيفة المساعدة" من أجل العثور على المكان المناسب لملف معين. الآن يمكنني استخدام نهج أبسط وأكثر قابلية للفهم: كل هذا يقع في مجلد
lib
واحد.
على المدى الطويل ، قد يتضح أن حجم هذا المجلد كبير جدًا بحيث يتعين عليك تنظيمه بطريقة أو بأخرى ، لكن هذا طبيعي تمامًا. من الأسهل دائمًا تجهيز شيء ما بهيكل معين بدلاً من التخلص من أخطاء الهيكلة المفرطة.
في مشروع مؤشر الترابط الخاص بنا ، يحتوي مجلد
lib
على حوالي 100 ملف. وهي مقسمة بالتساوي تقريبًا إلى ملفات تحتوي على تطبيق ميزات معينة ، وفي ملفات اختبار. لم يسبب أي صعوبات في العثور على الملفات الضرورية. بفضل
lib/name_of_thing
البحث الذكية المدمجة في معظم المحررين ، يجب علي دائمًا إدخال شيء مثل
lib/name_of_thing
، وما أحتاج إليه موجود.
بالإضافة إلى ذلك ، لدينا اسم مستعار يبسط عملية الاستيراد من مجلد
lib
، مما يتيح لك استخدام أوامر من هذا النوع:
import formatPrice from 'lib/format_price'
لا تنزعج من هياكل المجلدات المسطحة التي يمكن أن تسبب تخزين ملفات متعددة في مجلد واحد. عادة ما يكون هذا الهيكل هو كل ما هو مطلوب لمشروع معين.
إخفاء مكتبات الجهات الخارجية خلف واجهات برمجة التطبيقات الأصلية
أنا حقا أحب نظام
مراقبة علة
ترقب . كنت في كثير من الأحيان استخدامه عند تطوير أجزاء الخادم والعميل من التطبيقات. من خلال مساعدتها ، يمكنك التقاط استثناءات وتلقي إعلامات حول حدوثها. هذه أداة رائعة تتيح لنا مواكبة المشاكل التي تواجهها على الموقع.
عندما أستخدم مكتبة تابعة لجهة خارجية في مشروعي ، أفكر في كيفية القيام بذلك ، إذا لزم الأمر ، يمكن استبدالها بأسرع ما يمكن بشيء آخر. في كثير من الأحيان ، كما هو الحال مع نظام ترقب نفسه الذي نود حقا ، وهذا ليس ضروريا. لكن ، في حالة حدوث ذلك ، لا يؤلمك أبدًا التفكير في طريقة لتجنب استخدام خدمة معينة أو طريقة لتغييرها إلى شيء آخر.
أفضل حل لهذه المشكلة هو تطوير API الخاص بك الذي يخفي أدوات الآخرين. يشبه هذا إنشاء وحدة
lib/error-reporting.js
التي تقوم بتصدير الدالة
reportError()
. جوهر هذه الوحدة يستخدم ترقب. ولكن يتم استيراد ترقب مباشرة في هذه الوحدة وليس في أي مكان آخر. هذا يعني أن استبدال Sentry بأداة أخرى سيبدو بسيطًا للغاية. للقيام بذلك ، يكفي تغيير ملف واحد في مكان واحد. طالما بقيت API العامة لهذا الملف على حالها ، فلن يعرف باقي المشروع أنه عند استدعاء
reportError()
، لا يتم استخدام ترقب ، ولكن شيء آخر.
يرجى ملاحظة أن API العامة للوحدة تسمى الوظائف التي تصدرها والوسيطات الخاصة بها. يطلق عليهم أيضًا الواجهة العامة للوحدة.
استخدام PropTypes (أو أدوات مثل TypeScript أو Flow)
عندما أفعل البرمجة ، أفكر في ثلاثة إصدارات من نفسي:
- جاك من الماضي والرمز الذي كتبه (في بعض الأحيان رمز مشكوك فيه).
- جاك اليوم ، والرمز الذي يكتبه الآن.
- جاك من المستقبل. عندما أفكر في هذا المستقبل بنفسي ، أسأل نفسي الحاضر عن كيف يمكنني كتابة التعليمات البرمجية التي من شأنها أن تجعل حياتي أسهل في المستقبل.
قد يبدو الأمر غريبًا ، لكنني وجدت أنه من المفيد ، بالتفكير في كيفية كتابة التعليمات البرمجية ، طرح السؤال التالي: "كيف سيتم إدراكه خلال ستة أشهر؟".
إحدى الطرق البسيطة لجعل نفسك حاضراً وأكثر إنتاجية هي تحديد أنواع الخصائص (
PropTypes
) المستخدمة من قبل المكونات. هذا سيوفر الوقت في البحث عن الأخطاء المطبعية المحتملة. سيوفر لك هذا الحماية من المواقف التي يتم فيها استخدام خصائص الأنواع الخاطئة باستخدام المكون أو ينسى تمامًا نقل الخصائص. في حالتنا ،
تعد قاعدة eslint-react / prop-types بمثابة تذكير جيد بضرورة استخدام
PropTypes
.
إذا ذهبت أبعد من ذلك ، فمن المستحسن وصف الخصائص بدقة قدر الإمكان. على سبيل المثال ، يمكنك القيام بذلك:
blogPost: PropTypes.object.isRequired
ولكن سيكون من الأفضل بكثير القيام بذلك:
blogPost: PropTypes.shape({ id: PropTypes.number.isRequired, title: PropTypes.string.isRequired,
في المثال الأول ، يتم إجراء التحقق الأدنى الضروري. في الثانية ، يتم إعطاء المطور معلومات أكثر فائدة بكثير. ستكون سهلة الاستخدام ، على سبيل المثال ، إذا نسي شخص ما حقلاً معينًا يستخدم في الكائن.
تُستخدم مكتبات الجهات الخارجية فقط عند الحاجة إليها حقًا.
هذه النصيحة أكثر أهمية من أي وقت مضى مع ظهور
خطافات React . على سبيل المثال ، شاركت في تغيير كبير لأحد أجزاء موقع مؤشر الترابط وقررت إيلاء اهتمام خاص لاستخدام مكتبات الطرف الثالث. , , . ( ), .
, React-. — , , React API Context, .
, , Redux, . , ( , ). , , , .
— , , . .
, . , . , « ». , , , . . «» - , . , , .
Redux. . , . , ,
user_add_to_cart
, . . , , Redux, . , Redux , .
, , , , :
- , , . .
- , , . , .
- , - , . , , .
- , . , , . , , , «» .
, , API Context
- .
, (, ,
). : , .
, , , . :
const wrapper = mount( <UserAuth.Provider value=> <ComponentUnderTest /> </UserAuth.Provider> )
:
const wrapper = mountWithAuth(ComponentUnderTest, { name: 'Jack', userId: 1, })
:
- . — , , , .
- —
mountWithAuth
. , .
,
test-utils.js
. , — . .
النتائج
. , , , , . , , . , : . . - , .
أعزائي القراء! React-?
