إذا كنت محترفًا بالفعل ، فربما تتذكر عكازاتك. أو ربما تقديم حلول أفضل للمشاكل الموصوفة.
ستركز هذه المقالة على رأيي الشخصي حول كيفية تنظيم تكوين المكونات.
لنبدأ صغيرًا
لنفكر في بعض الأشكال المجردة. سنعني أن هناك العديد من الحقول في النموذج (حوالي 10-15 قطعة) ، ولكن حتى لا تتدفق العيون ، سنأخذ نموذجًا يحتوي على 4 حقول كمثال.
يصل كائن متعدد المستويات من النوع التالي إلى مدخل المكون:
const unit = {
name: 'unit1',
color: 'red',
size: {
width: 2,
height: 4,
},
}
مطور عديم الخبرة (مثلي في الشهر الأول من العمل مع رد فعل) سيفعل كل هذا في مكون واحد حيث سيتم تخزين قيم الإدخال في الحالة:
const Component = ({ values, onSave, onCancel }) => {
const [ state, setState ] = useState({});
useEffect(() => {
setState(values);
}, [ values, setState ]);
return <div className="form-layout">
<div className="form-field">
<Input onChange={({ target: { value } }) =>
setState((state) => ({...state, name: value }))
}/>
</div>
<div className="form-field">
<Input onChange={({ target: { value } }) =>
setState((state) => ({...state, color: value }))
}/>
</div>
<div className="size">
<div className="form-field">
<Input onChange={({ target: { value } }) =>
setState((state) => ({...state, size: { width: value } }))
}/>
</div>
<div className="form-field">
<Input onChange={({ target: { value } }) =>
setState((state) => ({...state, size: { height: value } }))
}/>
</div>
</div>
<div className="buttons">
<Button onClick={() => onSave(state)}>Save</Button>
<Button onClick={() => onCancel()}>Cancel</Button>
</div>
</div>
}
بالنظر إلى مدى سرعة تعامل المطور معها ، سيعرض العميل إنشاء نموذج آخر بناءً على هذا النموذج ، ولكن بدون كتلة "الحجم".
هناك خياران (وكلاهما غير صحيح):
- يمكنك نسخ المكون الأول وإضافة ما هو مفقود أو إزالة الفائض. يتم ذلك عادةً عندما لا يأخذون المكون الخاص بهم كأساس ويخشون كسر شيء ما فيه.
- أضف إعدادات مكون إضافية إلى المعلمات.
إذا انتهى المشروع بعد تنفيذ 3-5 أشكال ، فإن المطور سيكون محظوظًا.
ولكن عادة ما تكون هذه مجرد البداية ، وعدد القوالب المختلفة في تزايد.
ثم يتطلب الأمر نموذجًا مشابهًا ، ولكن بدون كتلة "اللون".
ثم واحدة مماثلة ، ولكن مع كتلة "وصف" جديدة.
ثم قم بعمل بعض الكتل للقراءة فقط.
ثم يجب إدخال نموذج مشابه في شكل آخر - بشكل عام ، الحزن ، والذي يأتي أحيانًا من هذا.
أشكال جديدة عن طريق النسخ
سيكون المطور الذي يتبع نهج النسخ السريع بالطبع سريعًا في تنفيذ أشكال جديدة. بينما سيكون هناك أقل من 10. ولكن بعد ذلك سينخفض المزاج تدريجياً.
خاصة عندما يحدث إعادة التصميم. قم بتصحيح المسافات البادئة بين كتل النموذج "قليلاً" ، قم بتغيير مكون اختيار اللون. بعد كل شيء ، لا يمكن توقع كل شيء في وقت واحد وسيتعين مراجعة العديد من حلول التصميم بعد تنفيذها.
من المهم الانتباه إلى تكرار الإشارة إلى "شكل مماثل". بعد كل شيء ، المنتج واحد ويجب أن تكون جميع القوالب متشابهة. نتيجة لذلك ، يتعين عليك التعامل مع العمل الروتيني غير المثير للاهتمام بشأن إعادة صياغة نفس الشيء في كل نموذج ، وبالمناسبة ، سيحتاج المختبرين أيضًا إلى التحقق مرة أخرى من كل نموذج.
بشكل عام ، تحصل على الفكرة. لا تنسخ مكونات مماثلة.
أشكال جديدة بالتعميم
إذا اختار المطور المسار الثاني ، فهو بالطبع يمتطي حصانًا - قد تعتقد ذلك. يحتوي على عدد قليل من المكونات التي يمكنك من خلالها رسم عشرات الأشكال. تصحيح المسافة البادئة في جميع أنحاء المشروع أو تغيير مكون "اللون" هو تصحيح سطرين في الكود وسيتعين على المختبر إعادة التحقق في مكانين فقط.
لكن في الواقع ، أدى هذا المسار إلى ظهور عنصر صعب للغاية للحفاظ عليه.
من الصعب استخدامه ، tk. العديد من المعلمات ، بعضها يسمى تقريبًا نفس الشيء ، لفهم مسؤولية كل معلمة ، تحتاج إلى الدخول في الدواخل.
<Component
isNameVisible={true}
isNameDisabled={true}
nameLabel="Model"
nameType="input"
isColorVisible={true}
isColorDisabled={false}
colorType={'dropdown'}
isSizeVisible={true}
isHeightVisible={true}
isWidthDisabled={false}
/>
من الصعب أيضًا الحفاظ عليها. كقاعدة عامة ، هناك ظروف متشابكة معقدة في الداخل ويمكن أن تؤدي إضافة حالة جديدة إلى كسر كل شيء آخر. قد يؤدي التغيير والتبديل في المكون لإخراج نموذج واحد إلى كسر الباقي.
بشكل عام ، تحصل على الفكرة. لا تجعل المكون العديد من الخصائص.لحل مشاكل الخيار الثاني ، يبدأ المطورون ماذا؟ حق. كمطورين حقيقيين ، بدأوا في تطوير شيء يجعل من السهل إعداد مكون معقد.
على سبيل المثال ، اجعل معلمة الحقول (حسنًا ، مثل الأعمدة في جدول التفاعلات). ويتم تمرير معلمات الحقول هناك: أي حقل مرئي ، وما هو غير قابل للتحرير ، اسم الحقل.
يتحول استدعاء المكون إلى هذا:
const FIELDS = {
name: { visible: true, disabled: true, label: 'Model', type: 'input' },
color: { visible: true, disabled: false, type: 'dropdown' },
size: { visible: true },
height: { visible: true },
width: { disabled: false },
}
<Component
values={values}
fields={FIELDS}
/>
نتيجة لذلك ، يفخر المطور بنفسه. قام بتعميم الإعدادات لجميع الحقول وتحسين الكود الداخلي للمكون: الآن لكل حقل يتم استدعاء وظيفة واحدة ، والتي تحول التكوين إلى دعائم للمكون المقابل. حتى حسب اسم النوع ، يتم عرض مكون مختلف. أكثر من ذلك بقليل وستحصل على إطار العمل الخاص بك.
رائع؟ كثير جدا.
نأمل ألا يتحول إلى هذا:
const FIELDS = {
name: getInputConfig({ visible: true, disabled: true, label: 'Model'}),
color: getDropDownConfig({ visible: true, disabled: false}),
size: getBlockConfig({ visible: true }),
height: getInputNumberConfig({ visible: true }),
width: getInputNumberConfig({ disabled: false }),
}
<Component
values={values}
fields={FIELDS}
/>
بشكل عام ، تحصل على الفكرة. لا تعيد اختراع العجلة.
أشكال جديدة من خلال تكوين المكونات والأشكال المتداخلة
دعونا نتذكر ما ما زلنا نكتب عليه. لدينا بالفعل مكتبة تفاعل. ليست هناك حاجة لاختراع أي تصميمات جديدة. تم وصف تكوين المكون في رد الفعل باستخدام ترميز JSX
const Form1 = ({ values }) => {
return <FormPanel>
<FormField disabled label=”Model”>
<Input name="name" />
</FormField>
<FormField disabled label=”Color”>
<DropDown name="color" />
</FormField>
<FormPanel>
<FormField disabled label="Height">
<Input name="height" />
</FormField>
<FormField disabled label="Width">
<Input name="width" />
</From Field>
</FormPanelt>
</FormPanel>
}
يبدو أننا عدنا إلى خيار النسخ الأول. لكن في الواقع لا. هذا هو التكوين الذي يقضي على مشاكل النهجين الأولين.
هناك مجموعة من الطوب يتم تجميع النموذج منها. كل لبنة مسؤولة عن شيء مختلف. بعضها للتخطيط والمظهر ، وبعضها لإدخال البيانات.
إذا كنت بحاجة إلى تغيير المسافات البادئة في المشروع بأكمله ، فهذا يكفي للقيام بذلك في مكون FormField. إذا كنت بحاجة إلى تغيير عمل القائمة المنسدلة ، فسيتم ذلك في مكان واحد في مكون القائمة المنسدلة.
إذا كنت بحاجة إلى شكل مشابه ، ولكن على سبيل المثال ، بحيث لا يوجد حقل "لون" ، فإننا نضع الكتل المشتركة في قوالب منفصلة ونقوم بتجميع شكل آخر.
ننقل كتلة الحجم إلى مكون منفصل:
const Size = () => <FormPanel>
<FormField disabled label="Height">
<Input name="height" />
</FormField>
<FormField disabled label=”Width”>
<Input name="width" />
</From Field>
</FormPanel>
صنع شكل باختيار الألوان:
const Form1 = () => <FormPanel>
<FormField disabled label="Color">
<DropDown name="color" />
</FormField>
<FormField disabled label="Model">
<Input name="name" />
</FormField>
<Size name="size" />
</FormPanel>
نصنع شكلًا مشابهًا ، لكن بدون اختيار لون:
const Form2 = () => <FormPanel>
<FormField disabled label="Model">
<Input name="name" />
</FormField>
<Size name="size" />
</FormPanel>
الأهم من ذلك ، أن الشخص الذي يحصل على مثل هذا الرمز لا يحتاج إلى التعامل مع التكوينات الوهمية للسلف. كل شيء مكتوب بلغة JSX ، وهو مألوف لأي مطور تفاعل ، مع تلميحات المعلمات لكل مكون.
بشكل عام ، تحصل على الفكرة. استخدم JSX وتكوين المكون.
بضع كلمات عن الدولة
الآن دعونا ننتبه إلى الدولة. بتعبير أدق ، غيابه. بمجرد أن نضيف حالة ، نغلق تدفق البيانات ويصبح من الصعب إعادة استخدام المكون. يجب أن تكون جميع الطوب عديمة الجنسية (أي عديمة الجنسية). وفقط في المستوى الأعلى ، يمكن توصيل النموذج المُجمع من الطوب بالحالة. إذا كان النموذج معقدًا ، فمن المنطقي تقسيمه إلى عدة حاويات وربط كل جزء بالإعادة.
لا تكن كسولًا لإنشاء مكون منفصل عديم الجنسية. ثم ستتاح لك الفرصة لاستخدامه كجزء من نموذج آخر ، أو إنشاء نموذج كامل بناءً عليه ، أو حاوية للاتصال بالإعادة.
بالطبع ، في الطوب يمكن أن تكون هناك حالات لتخزين الحالة الداخلية غير المرتبطة بتدفق البيانات العام. على سبيل المثال ، في الحالة الداخلية القائمة المنسدلة (القائمة المنسدلة) ، من الملائم تخزين السمة سواء تم توسيعها أم لا.
بشكل عام ، تحصل على الفكرة. مكونات منفصلة إلى الحالة عديمي الجنسية و Statefull.
مجموع
والمثير للدهشة أنني أواجه بشكل دوري جميع الأخطاء الموضحة في المقالة والمشكلات التي تنشأ عنها. أتمنى ألا تكررها ثم يصبح الحفاظ على الكود أسهل بكثير.
سأكرر النقاط الرئيسية:
- لا تنسخ مكونات مماثلة. استخدم مبدأ الجفاف.
- لا تصنع مكونات بها الكثير من الخصائص والوظائف. يجب أن يكون كل مكون مسؤولاً عن شيء مختلف (مسؤولية واحدة من SOLID)
- مكونات منفصلة إلى الحالة عديمي الجنسية و Statefull.
- لا تعيد اختراع تصميماتك. استخدم JSX والتكوين من المكونات الخاصة بك.