ابدأ مع React


الدرس: شغّل التاثيرات (effects) مع useEffect


الصفحة السابقة
هل أخبرتك من قبل عن   render (التقديم) في تطبيق React؟

بمجرد حدوث تعديل في الدعامة (prop) أو الحالة(state) ، تتم إعادة تقديم المكون المعني وتوابعه.

ولكن ماذا لو كنت تريد القيام بعمل ليس جزءًا من العائد (return)  ؟ من الذي يتدخل بعد قيام React بتحديث DOM؟ على سبيل المثال ، ماذا لو كنت تريد تشغيل تنبيه في كل مرة يتم فيها تحديث سلة التسوق الخاصة بك؟ أو حتى حفظ هذه السلة مع كل تحديث؟

حسنًا ، تسمى هذه الأنواع من الإجراءات التاثيرات الجانبية (side effects)، ولهذا لدينا   useEffect . 😎 تسمح لنا بتنفيذ إجراء ما عند نقطة معينة في دورة حياة مكوناتنا.

اكتشف USEEFFECT


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

لذلك ، يكفي سطر صغير من التعليمات البرمجية في   Cart.js  :


alert(`J'aurai ${total}€ à payer 💸`)
 
لذلك نضعه مباشرة في المكون الخاص بنا ، قبل   return . هيا، جرّبها!

😨 عندما أقوم بالنقر ، يتم حظر الكود الخاص بي ولا يتم عرض القيمة الخاصة بي إلا بعد النقر فوق "موافق"! ماذا يحدث ؟

لا تنذعر ! صدقني: لن نتوقف عند هذا الحد.

بدلاً من ذلك ، سنستخدم ملفات    useEffect .

قم باستيراده كما فعلنا   useState   في    Cart.js  :


import { useState, useEffect } from 'react'
 
و استخدام هذا الكود بدلا من ذلك (لا يزال في Cart.js ) :

useEffect(() => {
    alert(`J'aurai ${total}€ à payer 💸`)
})
 
ما الذي يعطينا Cart.js :

function Cart({ cart, updateCart }) {
    const [isOpen, setIsOpen] = useState(true)
    const total = cart.reduce(
        (acc, plantType) => acc + plantType.amount * plantType.price,
            0
        )

    return isOpen ? (
        <div className='lmj-cart'>
            <button
                className='lmj-cart-toggle-button'
                onClick={() => setIsOpen(false)}
            >
                Fermer
            </button>
            {cart.length > 0 ? (
                <div>
                    <h2>Panier</h2>
                    <ul>
                        {cart.map(({ name, price, amount }, index) => (
                            <div key={`${name}-${index}`}>
                                    {name} {price}€ x {amount}
                            </div>
                        ))}
                    </ul>
                    <h3>Total :{total}€</h3>
                    <button onClick={() => updateCart([])}>Vider le panier</button>
                </div>
            ) : (
                <div>Votre panier est vide</div>
            )}
        </div>
    ) : (
        <div className='lmj-cart-closed'>
            <button
                className='lmj-cart-toggle-button'
                onClick={() => setIsOpen(true)}
            >
                Ouvrir le Panier
            </button>
        </div>
    )
}
 
وهذا كل شيء! كل شيء يسير كما هو متوقع ، لسبب بسيط وهو أن   useEffect   يُمكّننا من تنفيذ تأثيرنا بمجرد تقديم المكون . وبما ان  useEffect   هو    مباشرة في مكوننا ، لدينا اتصال مباشر إلى حالتنا ، إلى متغيراتنا ، دعائمنا ، السحر أليس كذلك؟

لكن انتظر ، ماذا يحدث إذا أغلقت سلة التسوق الخاصة بي؟

لا! 😭 ينطلق تنبيهي أيضًا!

حسنًا ، هذا طبيعي: لقد أخبرتك أن useEffect    يشتغل   بعد التقديم. حسنًا ، يتم إطلاقه بعد كل عرض للمكون. إلا إذا كنت ...

حدد متى يتم تشغيل التأثير باستخدام جدول التبعية


لتقرر بدقة متى تريد تشغيل تأثير ما ، يمكنك استخدام جدول التبعية. يتوافق مع المعلمة الثانية التي تم تمريرها إلى    useEffect .

تذكير سريع: المعلمة الأولى التي تم تمريرها إلى useEffect هي دالة.

تتوافق هذه الوظيفة مع التأثير الذي يتعين القيام به . ها هو:


() => {
    alert(`J'aurai ${total}€ à payer 💸`)
}
 
تقبل useEffect    المعلمة الثانية   مصفوفة مدوّنة بين قوسين مربعين  : هذه هي مصفوفة التبعية.

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


useEffect(() => {
    alert(`J'aurai ${total}€ à payer 💸`)
}, [total])
 
يمكنك وضع أي متغير هنا. إذا كنت ترغب في عرض التنبيه عند إجمالي التغييرات أو عند تحديد فئة جديدة ، يمكنك فعل ما يلي:

  • استرداد الفئة المختارة (عن طريق الصعود   activeCategory   و   setActiveCategory   وتمريرها كما الدعائم)؛
  • ثم ضع   [total, activeCategory]   في جدول التبعية الخاص بك. 
حاول أن ترى!

يتم عرض التنبيه عندما تتغير الفئة أو عندما يتغير الإجمالي.

و ... هل التأثير نشط على أول تقديم للمكوِّن الخاص بي؟

حاول تحديث الصفحة لترى! يتم عرض التنبيه. لذا الجواب نعم .

علاوة على ذلك ، هذا السؤال يجعلني أرتد على سؤال آخر:

حسنًا ، في هذه الحالة ، عليك وضع جدول تبعية فارغ :

useEffect(() => {
    alert('Bienvenue dans La maison jungle')
}, [])
 
طالما أنك تستخدم جدول التبعيات ، فاحرص على عدم نسيان أي تبعيات ، أو ترك بعضها لا علاقة له بها ، لتجنب الجري في الأوقات غير المناسبة.

تغيير عنوان علامة التبويب الخاصة بك


حسنًا ، لقد بدأت أشعر بالضيق من كل هذه التنبيهات. بدلا من ذلك، أريد أن أستخدم   useEffect   ل تحديث عنوان التبويب لمتصفحي .

React
هل ترى ما أتحدث عنه؟

لذلك سنستخدم  document.title   دائمًا    Cart.js، كما هو الحال هنا:


useEffect(() => {
    document.title = `LMJ: ${total}€ d'achats`
}, [total])
 
وهذا كل شيء! يتغير عنوان علامة التبويب الخاصة بنا وفقًا لإجمالي سلة لدينا! 🎉
React
useEffect يغير عنوان علامة التبويب لدينا إلى The Jungle House

إتقان قواعد الاستخدام



دمج مراحل الاستخدام المختلفة

لنستعرض ما رأيناه للتو من useEffect والاستخدامات الأخرى في هذا الفيديو!


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

ادمج بعض القواعد


كما شرحت لك في الفصل السابق ،   useEffect   هو خطاف(hook) ، وظيفة تسمح لك "بتوصيل" وظيفة تأثيرات React . لكن بعض القواعد الخاصة تنطبق على الخطاف(hook)    useEffect  :

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

الخطافات (hooks) حديثة جدًا. يتمتع مطورو React بإمكانية الوصول إليها منذ أوائل عام 2019. قبل ذلك ، لم يكن من الممكن الوصول إلى الحالة أو التأثيرات من وظائف المكونات. إذا أردنا استخدام أحد الآثار الجانبية أو الحالة المحلية ، كان علينا المرور بمكوِّن فئة. يمكنك أن تعتبر نفسك سعيدًا بإمكانية الوصول إلى الخطافات في وقت مبكر من تعلمك لـ React ، حيث إنها تتمتع بالعديد من المزايا للمطورين:
  • تتطلب كتابة كود أقل ؛
  • لذلك من الأسهل اختبارها ؛
  • ولكن أيضًا أكثر قابلية للقراءة.

ممارسة


React
سنكون الآن قادرين على تطبيق ما تعلمته. كما هو الحال دائمًا ، ستجد قاعدة التعليمات البرمجية في فرع P3C3-Begin .

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

  • احفظ السلة عند كل تعديل باستخدام   localStorage.setItem()  . انتبه ، لقد أصبحت السلة الآن كائنًا ، سيتعين عليك المرور   JSON.stringify بـ  (  لديك الوثائق هنا ) ثم(   JSON.parse    ومرة أخرى التوثيق هنا ) ؛
  • تأكد من عدم حفظ سلة التسوق مرات أكثر من اللازم ؛
  • استرداد السلة في المرة الأولى التي يتم فيها تحميل الصفحة    localStorage.getItem .
بمجرد الانتهاء ، ستتمكن من مقارنة الكود الخاص بك مع الرمز الخاص بي في P3C3-Solution .

باختصار


  • useEffect يسمح بتنفيذ التأثيرات: هذا يسمح للمكون الخاص بنا بتنفيذ الإجراءات بعد العرض ، واختيار وقت تنفيذ هذا الإجراء.
  •    يتم استدعاء الخطاف  ((hook useEffect بعد كل عرض للمكون الخاص بك. من الممكن تحديد تعديل البيانات الذي يطلق التأثيرات المنفذة في useEffect ، باستخدام جدول التبعية.
  • يتيح لك جدول التبعية الفارغ تشغيل تأثير فقط في المرة الأولى التي تقوم فيها بتقديم المكون الخاص بك.
تهانينا ! لقد أوشكت على الانتهاء من هذه الدورة التدريبية - لم يتبق لديك سوى اختبار واحد فقط 🎉 بعد ذلك ، في الختام ، سنقوم بتلخيص بسيط لما تعلمته ، وسأقدم لك بعض النصائح لمواصلة تعلمك. لذلك اراك على الفور! 😊