قم بإنشاء تطبيق React من البداية (الجزء 7): إعداد React وأفضل الممارسات

هذه المشاركة جزء من سلسلة منشورات على مستوى المبتدئين مخصصة للأشخاص الذين يستخدمون
أدوات أو قوالب أو قوالب جاهزة لـ React لكن ترغب في معرفة وفهم كيفية إنشاء تطبيق React من البداية.

جميع المشاركات في هذه السلسلة:
الجزء 1: مقدمة
الجزء 2: التهيئة والملف الأول
الجزء 3: استخدام بناء جملة ES2015
الجزء 4: فرض دليل الأنماط
الجزء 5: إعداد خادم Express
الجزء 6: استخدام محزم الوحدة النمطية
الجزء 7: إعداد رد الفعل وأفضل الممارسات
الجزء 8: إعداد مسترجع
الجزء 9: إعداد جهاز التوجيه التفاعلي
الجزء 10: TDD وإعداد Jest

إعداد رد فعل

في هذا المنشور ، سنقوم بإعداد React وإنشاء مكون بسيط جدًا ، ثم سنتناول بعضًا من أفضل الممارسات التي يجب وضعها في الاعتبار عند تطوير مكونات React. هذا هو المكان الذي يبدأ فيه الجزء الممتع ، لذا دعنا نتعمق فيه!

تثبيت حزم React و React Dom كتبعيات:

تثبيت npm $ - حفظ رد فعل dom

ثم افتح index.js وقم بإنشاء مكون React بسيط للغاية يمثل تطبيقنا. لدينا بالفعل عنصر مع تطبيق id في ملف القالب index.pug ، لذلك دعونا نستخدمه لتحميل التطبيق.

/ **
 * index.js
 * /
استيراد رد من "رد فعل" ؛
استيراد {تقديم} من 'react-dom' ؛
const MainApp = () => (
  

مرحبًا React!

// تقديم التطبيق
render (، document.getElementById ('app'))؛

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

سبب هذا الخطأ هو أن لدينا بناء جملة JSX داخل ملف index.js الخاص بنا والذي لم يفهمه Babel بعد. للسماح لـ Babel بترجمة بناء الجملة هذا إلى جافا سكريبت عادي ، سنستخدم إعداد React المسبق لـ Babel.

تثبيت الحزمة تبعية:

تثبيت $ npm - حفظ بابل مسبقا رد فعل

ثم أضف الإعداد المسبق إلى قائمة الإعدادات المسبقة في ملف .babelrc:

{
  "المسبقة": [
    "es2015"
    "مرحلة 0"،
    "تتفاعل"
  ]،
  "الإضافات": ["تحويل المتغيرات المضمنة في البيئة"]
}

يجب أن يكون هناك أيضًا خطأ في الفحص من شأنه أن يمنعك من بناء الحزمة. يشكو linter لأن index.js هو ملف JavaScript يحتوي على بناء جملة JSX ولكنه يستخدم امتداد js بدلاً من jsx.

يمكنك قراءة وصف هذه القاعدة هنا. ينص القسم "عندما لا تستخدمه" على عدم استخدام هذه القاعدة إذا كنت لا تهتم بتقييد امتداد الملفات التي تحتوي على بناء جملة JSX.

يمكنك الاستمرار في استخدام هذه القاعدة ، لكنني أفضل استخدام ملحق js لجميع الملفات ، لذا سأقوم بتعطيل هذه القاعدة:

{
  "يمتد": "airbnb" ،
  "env": {
    "es6": صحيح ،
    "المتصفح": صحيح ،
    "العقدة": صحيح
  }،
  "قواعد": {
    "react / jsx-filename-extension": 0
  }
}

تمكين HMR

يعد تمكين Hot Module Replacement بسيطًا مثل إضافة كتلة من التعليمات البرمجية:

/ **
 * index.js
 * /
استيراد رد من "رد فعل" ؛
استيراد {تقديم} من 'react-dom' ؛
if (module.hot) {
  module.hot.accept ()؛
}
const MainApp = () => (
  

مرحبًا React!

// تقديم التطبيق
render (، document.getElementById ('app'))؛

نصائح وأفضل الممارسات

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

واردات التبعية مقابل الواردات المحلية

افصل واردات التبعية عن الواردات المحلية بخط جديد. الواردات التبعية يجب أن تأتي أولاً.

import React، {Component} from 'react'؛
قم باستيراد أداة مفيدة من "وحدة مفيدة" ؛
استيراد myLocalModule من './my-local-module' ؛

مكونات الوظيفية عديمي الجنسية

إذا كان المكون مكونًا للتجسيد فقط أو لا يحتاج إلى استخدام كائن حالة ، فاستخدم وظيفة JavaScript بسيطة بدلاً من فئة. وهذا ما يسمى مكون وظيفي عديمي الجنسية.

لذا بدلاً من القيام بذلك:

import React، {Component} from 'react'؛
الطبقة MyComponent يمتد المكون {
  يجعل() {
    إرجاع (
      
مرحبا!     )؛   } }
تصدير الافتراضي MyComponent ؛

افعل هذا:

استيراد رد من "رد فعل" ؛
const MyComponent = () => 
مرحبًا! ؛
تصدير الافتراضي MyComponent ؛

ترى كم تمت إزالة الفوضى؟ يمكنك أيضًا جعلها أكثر بساطة عن طريق تصدير الوظيفة نفسها:

استيراد رد من "رد فعل" ؛
export default () => 
مرحبًا! ؛

ومع ذلك ، أنا لا أفضل القيام بذلك لأنه يجعل تصحيح الأخطاء أصعب. إذا قمت بالتحقق من أدوات React Dev Tools ، فسترى أن اسم المكون هو "Unknown" لأن الوظيفة مجهولة.

مكون وظيفي مجهول

تتمثل الطريقة الأفضل في استخدام دالة مسماة عادية بدلاً من دالة مجهولة:

استيراد رد من "رد فعل" ؛
وظيفة التصدير الافتراضية MyComponent () {
  return 
مرحبًا! ؛ }
مكون وظيفي مسمى

ابدأ بمكونات العرض التقديمي

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

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

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

تقليل استخدام الدولة

استخدم الحالة في مكوناتك وتأكد من أنها تستخدم الحالة لـ UI بدلاً من البيانات ، بمعنى آخر ، إذا كنت لا تستخدمها في التقديم () فلا يجب أن تكون في الحالة. تذكر أنه يجب عليك استخدام setState فقط إذا كنت تريد إعادة تقديم المكون الخاص بك.

دعنا نقول أن لدينا مكون يتكون من زر واحد. قد يتم النقر فوق هذا الزر مرة واحدة فقط ، وعند النقر فوقه ، سيتم تسجيل رسالة إلى وحدة التحكم:

import React، {Component} from 'react'؛

الطبقة MyComponent يمتد المكون {
  الولاية = {
    clickOnce: false ،
  }؛
  handleClick = () => {
    إذا (! this.state.clickedOnce) {
      console.log ( 'النقر')؛
    }
    this.setState ({
      النقر فوق مرة واحدة: صحيح ،
    })؛
  }
  componentDidUpdate () {
    console.log ( 'محدث!')؛
  }
  يجعل() {
    إرجاع (
      
        <زر onClick = {this.handleClick}> انقر فوقي            )؛   } }
تصدير الافتراضي MyComponent ؛

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

إعادة تقديم التطبيق عند النقر على زر

سيكون هذا أفضل:

import React، {Component} from 'react'؛

الطبقة MyComponent يمتد المكون {
  clickedOnce = خطأ ؛
  
  handleClick = () => {
    إذا (! this.clickedOnce) {
      console.log ( 'النقر')؛
    }
    this.clickedOnce = صحيح ؛
  }
  componentDidUpdate () {
    console.log ( 'محدث!')؛
  }
  يجعل() {
    إرجاع (
      
        <زر onClick = {this.handleClick}> انقر فوقي            )؛   } }
تصدير الافتراضي MyComponent ؛

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

تحديد دائما propTypes و defaultProps

يجب أن تحتوي كافة المكونات على propTypes و defaultProps المعرّفة على أنها عالية قدر الإمكان داخل المكون. أنها بمثابة وثائق المكون ويجب أن تكون مرئية على الفور للمطورين الآخرين قراءة الملف.

منذ React v15.5 ، انتقلت React.PropTypes إلى حزمة مختلفة ، لذلك دعونا نقوم بتثبيت تلك الحزمة كتبعية:

تثبيت $ npm - حفظ أنواع الدعامة

للمكونات الوظيفية عديمي الجنسية:

يتم رفع الوظائف في JavaScript ، مما يعني أنه يمكنك استخدام دالة قبل إعلانها:

استيراد رد من "رد فعل" ؛
استيراد PropTypes من "أنواع prop" ؛
MyComponent.propTypes = {
  العنوان: PropTypes.string ،
}؛
MyComponent.defaultProps = {
  العنوان: "عداد بسيط" ،
}؛
وظيفة التصدير الافتراضية MyComponent (props) {
  return 

{props.title}

؛ }

ستشكو ESLint من استخدام الوظيفة قبل تعريفها ، ولكن من أجل توثيق أفضل للمكونات ، فلنقم بتعطيل قاعدة الوبر هذه للوظائف عن طريق تعديل ملف .eslintrc:

{
  ...
  "قواعد": {
    "react / jsx-filename-extension": 0 ،
    "عدم الاستخدام قبل التعريف": [
      "خطأ"،
      {
        "وظائف": خطأ
      }
    ]
  }
}

للمكونات القائمة على الفصل:

على عكس الوظائف ، لا يتم رفع الفئات في JavaScript ، لذلك لا يمكننا ببساطة القيام بـ MyComponent.propTypes = ... قبل تعريف الفئة نفسها ولكن يمكننا تعريف propTypes و defaultProps كخصائص للفئة الثابتة:

import React، {Component} from 'react'؛
استيراد PropTypes من "أنواع prop" ؛
الطبقة MyComponent يمتد المكون {
  propTypes ثابت = {
    العنوان: PropTypes.string ،
  }؛
  defaultProps ثابت = {
    العنوان: "عداد بسيط" ،
  }؛
  يجعل() {
    return 

{this.props.title}

؛   } }
تصدير الافتراضي MyComponent ؛

تهيئة الدولة

يمكن تهيئة الحالة داخل مُنشئ المكون:

الطبقة MyComponent يمتد المكون {
  منشئ (الدعائم) {
    السوبر (الدعائم)؛
    هذا. الدولة = {
      العد: 0 ،
    }؛
  }
}

هناك طريقة أفضل لتهيئة الحالة كخاصية لفئة:

الطبقة MyComponent يمتد المكون {
  منشئ (الدعائم) {
    السوبر (الدعائم)؛
  }
  الولاية = {
    العد: 0 ،
  }؛
}

هذا يبدو أفضل بكثير وأنظف وأكثر قابلية للقراءة ويساهم أيضًا في توثيق المكونات. يجب تهيئة كائن الحالة بعد propTypes و defaultProps:

import React، {Component} from 'react'؛
استيراد PropTypes من "أنواع prop" ؛
الطبقة MyComponent يمتد المكون {
  // propTypes يأتي أولاً
  propTypes ثابت = {
    العنوان: PropTypes.string ،
  }؛
  // defaultProps يأتي في المرتبة الثانية
  defaultProps ثابت = {
    العنوان: "عداد بسيط" ،
  }؛
  // البناء يأتي هنا
  البناء() {
    ...
  }
  / / ثم تأتي الدولة
  الولاية = {
    العد: 0 ،
  }؛
}

تمرير وظيفة ل setState

لا تشجع وثائق React الاعتماد على this.state وقيم this.props لحساب الحالة التالية لأن React يقوم بتحديثها بشكل غير متزامن. هذا يعني أن الحالة قد لا تتغير فورًا بعد استدعاء setState ().

الطبقة MyComponent يمتد المكون {
  الولاية = {
    عدد: 10 ،
  }
  onClick = () => {
    console.log (this.state.count)؛ // 10
    
    // العد لن يتغير على الفور
    this.setState ({count: this.state.count + this.props.step})؛
    
    console.log (this.state.count)؛ // لا يزال 10
  }
}

بينما يعمل هذا في سيناريوهات بسيطة وسيظل يتم تحديث الحالة بشكل صحيح ، إلا أنه قد يؤدي إلى سلوك غير متوقع في سيناريوهات أكثر تعقيدًا.

النظر في هذا السيناريو ، لديك مكون يجعل زر واحد. عند النقر فوق هذا الزر ، يتم استدعاء أسلوب handleClick:

الطبقة MyComponent يمتد المكون {
  defaultProps ثابت = {
    الخطوة: 5 ،
  }
  propTypes ثابت = {
    الخطوة: PropTypes.number ،
  }
  
  الولاية = {
    عدد: 10 ،
  }
  
  handleClick = () => {
    this.doSomething ()؛
    this.doSomethingElse ()؛
  }
  doSomething = () => {
    this.setState ({count: this.state.count + this.props.step})؛
  }
  doSomethingElse = () => {
    this.setState ({count: this.state.count - 1}) ؛
  }
  يجعل() {
    إرجاع (
      
        

العدد الحالي هو: {this.state.count}

        <زر onClick = {this.handleClick}> انقر فوقي            )؛   } }

يستدعي الزر handleClick () عند النقر فوقه ، والذي بدوره يستدعي doSomething () ثم doSomethingElse (). كلتا الدالتين ستعدلان قيمة العد داخل الولاية.

منطقيا ، 10 + 5 هو 15 ثم طرح 1 والنتيجة يجب أن تكون 14 ، أليس كذلك؟ حسنًا ، في هذه الحالة ، ليست - قيمة العد بعد النقرة الأولى هي 9 وليس 14. يحدث هذا لأن قيمة this.state.count لا تزال 10 عندما يتم استدعاء doSomethingElse () وليس 15.

لإصلاح ذلك ، يمكنك استخدام نموذج آخر من setState () يقبل دالة بدلاً من كائن. ستتلقى هذه الوظيفة الحالة السابقة كالوسيطة الأولى ، والدعائم في الوقت الذي يتم فيه تطبيق التحديث كالوسيطة الثانية:

this.setState ((prevState ، props) => ({
  العد: prevState.count + props.step
}))

يمكننا استخدام هذا النموذج لإصلاح مثالنا:

الطبقة MyComponent يمتد المكون {
  ...
  handleClick = () => {
    this.doSomething ()؛
    this.doSomethingElse ()؛
  }
  doSomething = () => {
    this.setState ((prevState ، props) => ({
      العد: prevState.count + props.step
    }))؛
  }
  doSomethingElse = () => {
    this.setState (prevState => ({
      العد: prevState.count - 1
    }))؛
  }
  ...
}

مع هذا التطبيق ، يتم تحديث الحساب بشكل صحيح من 10 إلى 14 إلى 18 وما إلى ذلك. الرياضيات بسيطة المنطقي مرة أخرى!

استخدام وظائف السهم كخصائص الفئة

لقد كانت هذه الكلمة الرئيسية مربكة دائمًا لمطوري JavaScript ولا يكون سلوكها مربكًا في مكونات React. هل تعرف كيف تتغير هذه الكلمة الرئيسية في مكون React؟ النظر في المثال التالي:

import React، {Component} from 'react'؛
الطبقة MyComponent يمتد المكون {
  الولاية = {
    العد: 0 ،
  }؛
  عند النقر() {
    console.log (this.state)؛
  }
  يجعل() {
    إرجاع (
      
        

العدد هو: {this.state.count}

        <زر onClick = {this.onClick}> انقر فوقي            )؛   } }
تصدير الافتراضي MyComponent ؛

سيؤدي النقر فوق الزر إلى حدوث خطأ:

TypeError Uncaught: لا يمكن قراءة خاصية 'state' غير محددة

وذلك لأن onClick ، ​​كطريقة فصل ، غير ملزم افتراضيًا. هناك عدة طرق لتصحيح هذا. (التورية المقصود ، الحصول عليها؟)

تتمثل إحدى الطرق في ربط الوظيفة بالسياق الصحيح أثناء قيامك بتمريرها داخل وظيفة render ():

<زر onClick = {this.onClick.bind (this)}> انقر فوقي 

أو يمكنك تجنب تغيير السياق باستخدام دالة سهم في التقديم ():

<زر onClick = {e => this.onClick (e)}> انقر فوقي 

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

import React، {Component} from 'react'؛
الطبقة MyComponent يمتد المكون {
  منشئ (الدعائم) {
    السوبر (الدعائم)؛
    this.onClick = this.onClick.bind (هذا) ؛
  }
  ...
  يجعل() {
    ...
    <زر onClick = {this.onClick}> انقر فوقي 
    ...
  }
}
تصدير الافتراضي MyComponent ؛

هذه التقنية أفضل ، لكن يمكنك بسهولة الحصول عليها وتنتهي بشيء يشبه هذا:

منشئ (الدعائم) {
  // هذا سيء ، سيء حقًا
  this.onClick = this.onClick.bind (هذا) ؛
  this.onChange = this.onChange.bind (هذا) ؛
  this.onSubmit = this.onSubmit.bind (هذا) ؛
  this.increaseCount = this.increaseCount.bind (this)؛
  this.decreaseCount = this.decreaseCount.bind (هذا) ؛
  this.resetCount = this.resetCount.bind (هذا) ؛
  ...
}

بما أننا نستخدم Babel ولدينا دعم لخصائص الفصل ، فإن الطريقة الأفضل هي استخدام وظائف السهم عند تحديد أساليب الفصل:

الطبقة MyComponent يمتد المكون {
  ...
  onClick = () => {
    // "هذا" محفوظ
    console.log (this.state)؛
  }
  يجعل() {
    إرجاع (
      
        

تحليل {this.state.count}         <زر onClick = {this.onClick}> انقر فوقي            )؛   } }

تدمير كائن الدعائم

عندما يكون للمكون العديد من الدعائم ، قم بتدمير كائن الدعائم بوضع كل خاصية على خطها الخاص.

للمكونات الوظيفية عديمي الجنسية:

وظيفة التصدير الافتراضية MyComponent ({
  الاسم الاول،
  الكنية،
  عنوان بريد الكتروني،
  وصف،
  على التغيير،
  عند تقديم،
}) {
  إرجاع (
    
      

تحليل {الاسم الأول}       ...        )؛ }

الوسائط الافتراضية ليست عذرا لإسقاط defaultProps. كما ذكرنا سابقًا ، يجب عليك دائمًا تحديد propTypes و defaultProps.

للمكونات القائمة على الفصل:

الطبقة MyComponent يمتد المكون {
  ...
  يجعل() {
    مقدار ثابت {
      الاسم الاول،
      الكنية،
      عنوان بريد الكتروني،
      وصف،
      على التغيير،
      عند تقديم،
    } = this.props؛
    إرجاع (
      
        

تحليل {الاسم الأول}         ...            )؛   } }

هذا أنظف ، ويسهل إعادة ترتيب الخصائص ويسهل إضافة / إزالة الخصائص إلى / من القائمة أثناء إنشاء فرق قابل للقراءة لـ Git. النظر في ما يلي:

يكون ديف-جي أكثر قابلية للقراءة عندما تكون كل خاصية في سطر جديد

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

التقديم الشرطي

عندما تحتاج إلى تقديم واحد من مكونين أو كتل من كود JSX بناءً على شرط ، استخدم تعبير ثلاثي.

isLoggedIn
  ؟ 
مرحبًا ، {اسم المستخدم}!   :

إذا كان الرمز يتكون من أكثر من سطر ، فاستخدم الأقواس:

isLoggedIn؟ (
  
    مرحبًا ، {اسم المستخدم}!    ): (   <زر onClick = {this.login}>     تسجيل الدخول    )

إذا كنت بحاجة إلى تقديم مكون واحد أو مقطع من كود JSX استنادًا إلى شرط ، فاستخدم تقييم دائرة قصر بدلاً من ذلك:

isComplete && 
لقد انتهيت!

لأكثر من سطر ، استخدم الأقواس:

isComplete && (
  
    انتهيت!    )

السمة الرئيسية

من الشائع استخدام Array.prototype.map وأساليب الصفيف المشابهة داخل وظيفة render () ومن السهل نسيان سمة المفتاح. المصالحة صعبة بما فيه الكفاية ، لا تجعل الأمر أكثر صعوبة. تذكر دائمًا وضع المفتاح في مكانه. (التورية المقصود مرة أخرى ، الحصول عليها؟)

يجعل() {
  إرجاع (
    
    {       {         items.map (item => (           
  •             {اسم العنصر}                    ))        }        )؛ }

عند استخدام map () أو filter () أو أساليب صفيف مشابهة ، فإن المعلمة الثانية لرد الاتصال هي فهرس العنصر. إنها فكرة سيئة بشكل عام استخدام هذا الفهرس كمفتاح. يستخدم React سمة المفتاح لتحديد العناصر التي تم تغييرها أو إضافتها أو إزالتها ويجب أن تكون قيمة المفتاح مستقرة ويجب أن تحدد كل عنصر بشكل فريد.

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

استخدم UUID أو ShortID لإنشاء معرف فريد لكل عنصر عند إنشائه لأول مرة واستخدامه كقيمة مفتاح.

تطبيع الدولة

حاول تطبيع كائن الحالة وإبقائه مسطحًا قدر الإمكان. تداخل البيانات في الحالة يعني منطقًا أكثر تعقيدًا مطلوبًا لتحديثه. تخيل كم سيكون قبيحًا تحديث حقل متداخل للغاية - انتظر ، لا تتخيل ، هنا:

// كائن الدولة
الولاية = {
  ...
  المشاركات: [
    ...،
    {
      التعريف: {
        المعرف: 12 ،
        مؤلف: '...'،
        العامة: خطأ ،
        ...
      }،
      ...
    }،
    ...
  ]،
  ...
}؛
// لتحديث "عام" إلى "حقيقي"
this.setState ({
  ... this.state،
  المشاركات: [
    ... this.state.posts.slice (0 ، الفهرس) ،
    {
      ... this.state.posts [المؤشر]،
      التعريف: {
        ... this.state.posts [المؤشر] الفوقية،
        العامة: صحيح ،
      }
    }،
    ... this.state.posts.slice (index + 1) ،
  ]
})؛

ليس هذا الرمز قبيحًا فحسب ، بل قد يُجبر أيضًا المكونات غير المرتبطة على إعادة تقديمها حتى لو لم تتغير البيانات التي تعرضها بالفعل. هذا لأننا قمنا بتحديث جميع الأجداد في شجرة الحالة بمراجع كائنات جديدة.

سيكون تحديث نفس الحقل أكثر بساطة إذا قمنا بإعادة هيكلة شجرة الحالة:

الولاية = {
  المشاركات: [
    10،
    11،
    12،
  ]،
  التعريف: {
    10:
      المعرف: 10 ،
      المؤلف: "المؤلف" ،
      العامة: خطأ ،
    }،
    11:
      المعرف: 11 ،
      المؤلف: "المؤلف ب" ،
      العامة: خطأ ،
    }،
    12:
      المعرف: 12 ،
      المؤلف: "المؤلف ج" ،
      العامة: خطأ ،
    }،
  }،
}
this.setState ({
  التعريف: {
    ... this.state.meta،
    [هوية شخصية]: {
      ... this.state.meta [معرف]،
      العامة: صحيح ،
    }
  }
})

استخدم أسماء الفصول الدراسية

إذا كنت في موقف كنت بحاجة فيه إلى استخدام اسم الفصل الشرطي ، فربما تكون قد كتبت شيئًا يشبه هذا:

  ...

هذا يصبح قبيحًا حقًا إذا كان لديك أسماء متعددة مشروطة. بدلاً من استخدام ثلاثية ، استخدم حزمة classnames:

استيراد أسماء الفئات من 'classnames' ؛
const classes = classnames ('tab'، {'is-active': isActive})؛
  ...

مكون واحد لكل ملف

هذه ليست قاعدة ثابتة ولكني أفضل الاحتفاظ بكل مكون في ملف واحد وتصدير هذا المكون بشكل افتراضي. ليس لدي أي سبب محدد لهذا ولكنني أجد أنه أكثر نظافة وتنظيمًا - خمسة مرتفعين إذا قمت بذلك أيضًا!

خاتمة

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

في الجزء التالي من هذه السلسلة ، سنقوم ببناء تطبيق مهام بسيط وتطبيق بعض من أفضل الممارسات والأنماط.

هل كانت هذه المقالة مفيدة؟ يرجى النقر على زر التصفيق أدناه ، أو متابعتي للمزيد.

شكرا للقراءة! إذا كان لديك أي ملاحظات ، فاترك تعليق أدناه.

انتقل إلى الجزء 7-ب: إنشاء تطبيق ToDo بسيط (قريبًا)