فصل الاهتمامات مع React hooks PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

فصل الاهتمامات مع خطافات React

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

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

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

مع إدخال خطافات React ، هناك طريقة جديدة لذلك: استخدام خطاطيف مخصصة.

لماذا يجب أن نفصل المنطق عن المكون؟

قبل أن نبدأ في فصل المنطق عن مكونات React ، يجب أن نعرف السبب.

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

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

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

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

كيفية فصل المنطق عن خطافات React

لفصل المنطق عن المكون الخاص بنا ، سننشئ أولاً خطافًا مخصصًا.

لنأخذ هذا المكون كمثال. تحسب القيمة الأسية للرقم الأساسي والأس:

يمكنك العثور على الكود المصدري الكامل هنا.

يبدو الرمز كما يلي:

export const ExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return (
    <div className="blue-wrapper">
      <input
        type="number"
        className="base"
        onChange={handleBaseChange}
        placeholder="Base"
        value={base}
      />
      <input
        type="number"
        className="exponent"
        onChange={handleExponentChange}
        placeholder="Exp."
        value={exponent}
      />
      <h1 className="result">{result}</h1>
    </div>
  );
};

قد يبدو هذا جيدًا بالفعل ، ولكن من أجل هذا البرنامج التعليمي ، فقط تخيل أن هناك المزيد من المنطق هنا.

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

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = (base ** exponent).toFixed(2);

  const handleBaseChange = (e) => {
    e.preventDefault();
    setBase(e.target.value);
  };

  const handleExponentChange = (e) => {
    e.preventDefault();
    setExponent(e.target.value);
  };

  return {
    base,
    exponent,
    result,
    handleBaseChange,
    handleExponentChange,
  };
};

export const ExponentCalculator = () => {
  const {
    base,
    exponent,
    result,
    handleExponentChange,
    handleBaseChange,
  } = useExponentCalculator();

  // ...
};

يمكننا تحريك هذا الخطاف إلى ملف منفصل لمزيد من الفصل بين الاهتمامات.

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

استخدمExponentCalculator.js

const calculateExponent = (base, exponent) => base ** exponent;

const useExponentCalculator = () => {
  const [base, setBase] = useState(4);
  const [exponent, setExponent] = useState(4);
  const result = calculateExponent(base, exponent).toFixed(2);

  // ...
};

يعد اختبار هذه الوظائف أسهل بكثير من اختبار رمز المكون بالكامل من المثال الأول. يمكننا اختبارها باستخدام أي مكتبة اختبار Node.js ، والتي لا تحتاج حتى إلى دعم مكونات React.

لدينا الآن الكود الخاص بإطار العمل (React) في الكود الخاص بالمكون والخطاف ، بينما يعيش منطق العمل لدينا في الوظائف المختلفة التي حددناها لاحقًا (والتي لا تراعي الإطار).

أفضل الممارسات

تسمية

أحب تسمية الخطافات المخصصة الخاصة بي بعد المكون كتسلسل لـ use واسم المكون (على سبيل المثال useExponentCalculator). ثم اتصل ب ملف نفسه كالخطاف.

قد ترغب في اتباع اصطلاح تسمية مختلف ، لكنني أوصي بذلك البقاء متسقًا في مشروعك.

إذا كان بإمكاني إعادة استخدام أجزاء من أداة ربط مخصصة ، فعادة ما أنقلها إلى ملف آخر ضمن src/hooks.

لا تبالغ

حاول أن تكون براغماتيًا. إذا كان المكون يحتوي على بضعة أسطر فقط من JS ، فليس من الضروري فصل المنطق.

CSS-في-JS

إذا كنت تستخدم مكتبة CSS-in-JS (useStyles) ، قد ترغب في نقل هذا الرمز إلى ملف آخر أيضًا.

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

وفي الختام

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

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

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

الطابع الزمني:

اكثر من حقيقة تفاعل المرمز