دو روش دیگر استفاده از context API (پایان فصل چهارم)

The Other Two Methods of Using the Context API

23 بهمن 1399
دو روش دیگر استفاده از context API (پایان فصل چهارم)

در قسمت قبل با context API و استفاده از آن آشنا شدیم. کدهایی که در جلسه ی قبل نوشتیم هیچ مشکلی ندارند اما دو روش دیگر استفاده از context برای کامپوننت های کلاس-محور و همچنین کامپوننت های کاربردی وجود دارد و در این جلسه می خواهیم به بررسی هر دو روش بپردازیم.

ما با کامپوننت Person.js شروع می کنیم که یک کامپوننت کلاس-محور است. ما می توانیم دو نقد منصفانه به روش قبلی کدنویسی خود داشته باشیم:

  <AuthContext.Consumer>
      {(context) => context.authenticated ? <p>Authenticated!</p> : <p>Please log in</p>}
  </AuthContext.Consumer>

نقد اول این است که کد بالا کمی شلوغ و به هم ریخته است و دفعه ی اولی که چشممان به چنین کدی میخورد قطعا سردرگم می شویم. در نقد دوم که نقد مهمی است می گوییم با روش قبلی کدنویسی فقط می توانیم از AuthContext درون کدهای JSX خود استفاده کنیم! به طور مثال اگر خواستیم از context درون componentDidMount (کدهای خارج از JSX) استفاده کنیم چه کار کنیم؟ فرض کنید ما بخواهیم درون componentDidMount یک درخواست HTTP ارسال کنیم که به اطلاعات authentication نیاز داشته باشد... با این روش نمی توانیم چنین کاری انجام دهیم.

روش اول: contextType برای کامپوننت های کاربردی

از نسخه ی 16.6 کتابخانه ی react روش دیگری برای کار معرفی شده است؛ باید یک خصوصیت static به نام contextType تعریف کنید. توجه داشته باشید که نام آن حتما باید contextType و دقیقا به همین شکلی که من نوشته ام باشد. اگر با برنامه نویسی شیء گرا آشنا باشید می دانید که static یعنی می توانیم از بیرون این کلاس و بدون ساخت شیء ای از کلاس مورد نظر، به این خصوصیت دسترسی داشته باشیم. مقدار این خصوصیت نیز باید AuthContext ما باشد (یا هر نامی که شما در هنگام ساخت auth-context.js برایش انتخاب کردید). من این کد را بالای تابع componentDidMount می نویسم:

    static contextType = AuthContext;

حالا برای تست آن می توانیم componentDidMount را بدین شکل تغییر دهیم:

    componentDidMount() {
        // this.inputElement.focus();
        this.inputElementRef.current.focus();
        console.log(this.context.authenticated);
    }

توجه داشته باشید که حتما باید this.context را به همین صورت this.context بنویسید و اجازه ی تغییر نام آن را ندارید.

حالا به جای کد زیر:

   <AuthContext.Consumer>
        {(context) => context.authenticated ? <p>Authenticated!</p> : <p>Please log in</p>}
    </AuthContext.Consumer>

می توانیم به راحتی بگوییم:

{this.context.authenticated ? <p>Authenticated!</p> : <p>Please log in</p>}

همانطور که می بینید کدهای ما چندین برابر خوانا تر و کدنویسی نیز بسیار آسان تر شد. فایل را ذخیره کرده و به مرورگر بروید. در قسمت console مرورگر باید چنین چیزی ببینید:

نمایش مقدار false برای authenticated
نمایش مقدار false برای authenticated

بله سه بار مقدار false به ما داده شده است. دلیل آن را می دانید؟ ما سه Person داریم (max و stephanie و manu) و در حالت پیش فرض state مربوط به authenticated برای هر سه نفر false است و پیام please log in برایشان نمایش داده می شود. از طرفی ما مقدار authenticated را درون componentDidMount قرار داده و آن را console.log کردیم که باعث چاپ شدن آن در کنسول مرورگر می شود. اگر روی دکمه ی log in نیز کلیک کنید هیچ مشکلی پیش نیامده و همه چیز به شکل قبل کار می کند.

این روش مخصوص کامپوننت های کلاس-محور است و من به شما پیشنهاد میکنم که از همین روش استفاده کنید چرا که هم کوتاه تر و خوانا تر است و هم اینکه به شما اجازه ی دسترسی به context را در خارج از JSX نیز میدهد.

روش دوم: useContext برای کامپوننت های کاربردی

روش دیگری نیز برای کامپوننت های کاربردی وجود دارد. متاسفانه از آنجایی که کامپوننت های کاربردی تنها یک تابع ساده هستند نمی توانیم خصوصیات static را در آن ها تعریف کنیم اما تیم react یک hook جدید به نام useContext به react اضافه کرده اند. برای استفاده از این hook باید ابتدا آن را import کنیم بنابراین به فایل Cockpit.js بروید (چرا که یک کامپوننت کاربردی است) و در آنجا می گوییم:

import React, { useEffect, useRef, useContext } from 'react';

حالا درون cockpit (مثلا پایین تر از toggleBtnRef) یک ثابت با هر نامی تعریف کنید (من نام آن را authContext میگذارم) و useContext را به آن می دهید:

    const authContext = useContext(AuthContext);

همانطور که می بینید useContext  به عنوان آرگومان، شیء AuthContext را از ما میگیرد. اگر از جلسات قبل یادتان باشد این شیء را با استفاده از دستور createContext ساخته بودیم (در فایل auth-context.js):

import React from 'react';

const authContext = React.createContext({
    authenticated: false,
    login: () => { }
});

export default authContext;

بنابراین می توانیم در cockpit.js بگوییم:

    console.log(authContext.authenticated);

همچنین در قسمت کدهای JSX آن نیز تغییراتی را ایجاد می کنیم. به جای کد زیر:

  <AuthContext.Consumer>
       {(context) => <button onClick={context.login}>Log in</button>}
  </AuthContext.Consumer>

می توانیم به راحتی بگوییم:

<button onClick={authContext.login}>Log in</button>

اگر به مرورگر رفته و دکمه ی log in را کلیک کنید، هیچ مشکلی نخواهیم داشت.

ما در ادامه ی دوره وارد مبحثی به نام redux می شویم که در این زمینه به ما کمک می کند اما یادگیری context API نیز بسیار مهم است و نمی توانستم بدون باز کردن این بحث از آن رد شوم.

این فصل که فصل چهارم از سری آموزشی react بود وارد عمیق ترین مباحث دنیای react شدیم و نه تنها ویژگی های مختلف و پیشرفته ای را یاد گرفتیم بلکه به پشت صحنه ی آن ها نیز نگاه انداختیم و با روند اجرای برنامه ها آشنا شدیم. متوجه هستم که این فصل یک فصل طولانی بود و اطلاعات بسیار زیادی در آن منتقل شد اما قبلا هم به شما گفته ام که هدف این فصل آشنایی کلی شما با این مسائل بود. در ادامه ی دوره ی آموزشی قرار است که از این ویژگی ها استفاده کنیم و مطمئن باشید به خاطر استفاده های مکرر از تمامی این ویژگی ها بر آن ها تسلط پیدا خواهید کرد. یادتان باشد که این فصل مانند یک رفرنس و دایرة المعارف react است بنابراین هر زمان که در طول دوره ویژگی خاصی را یادتان رفت به این فصل برگردید و آن را دوباره مطالعه کنید.

امیدوارم از مطالب این فصل لذت برده باشید. در فصل بعد (فصل پنجم) شروع به ساخت یک پروژه ی واقعی می کنیم. نگران نباشید من هم میدانم که هنوز مباحثی مانند ایجاد درخواست های HTTP و ... باقی مانده است. روش کار ما در این دوره بدین صورت است:

  • یادگیری مسائل پایه ای
  • کدنویسی نسخه ای ساده از پروژه ی عملی با استفاده از مباحث قبلی
  • یادگیری مباحث بیشتر
  • پیشرفته تر کردن پروژه ی عملی و تکمیل کدهای آن
  • یادگیری مباحث بیشتر
  • پیشرفته تر کردن پروژه ی عملی
  • و ....

بنابراین جای نگرانی نیست.

دانلود فایل های این جلسه

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری دوره جامع آموزش ری اکت توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

seyedbardia
22 اردیبهشت 1400
ممنون از اطلاعات عالیتون و زحمات فوق العاده ارزشمند و بینهایت از شما متشکرم. فقط یک مورد اینکه اگر اشتباه نکنم در روش اول باید نوشته بشود: روش اول: contextType برای کامپوننت های کلاس-محور که به اشتباه کاربردی تایپ شده است. باز هم ممنون از شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.