سلام عزیزان ، به پارت چهاردهم از سری مقالات " آموزش مقدماتی React" خیلی خوش اومدین . در این قسمت در اصل باید با مفهوم Context Api آشنا بشیم ، اما قبلش بهتره که مفهوم Prop Drilling رو کاور کنیم تا به این نتیجه برسیم که در چه مواقعی باید از Context Api استفاده کنیم !
در حالت کلی به فرآیند ارسال props از کامپوننت والد به یکی از کامپوننت های فرزند بصورت آبشاری در درخت کامپوننت ها ، Props Drilling گفته میشه . بزارین روون تر توضیح بدم :)
فرض کنین کلی کامپوننت داریم و میخوایم داده ای رو از طریق props از کامپوننت A انتقال بدیم به کامپوننت D . به اینصورت که دیتای مورد نظرمون رو اول از کامپوننت A انتقال میدیم به کامپوننت B و بعد از کامپوننت B انتقال میدیم به کامپوننت C و نهایتا از کامپوننت C هم انتقال میدیدم به کامپوننت D ! خوب اگر دقت کنیم متوجه میشیم که این مابین کامپوننت B و C اصلاً از اون دیتا استفاده نمیکنن و فقط وظیفه ی پاس دادن اون رو برعهده دارن ! کلیت Props Drilling همین چیزی بود که الان خوندین ، ولی به نظر من کافی نیست ! پس بیاین این موضوع رو یکم عمیق تر بررسی کنیم :)
احتمالا با مفهوم متغیرهای سراسری در دنیای برنامه نویسی آشنایی دارید . علت اینکه بعضی از برنامه نویس ها استفاده از متغیرهای سراسری رو دوست ندارن ، این هست که این کار ناچاراً موجب یک مدل داده ای گیج کننده در اپلیکیشن ها میشه ، یعنی با این کار پیدا کردن جایی که داده ای مقدار اولیه گرفته ، آپدیت شده و مورد استفاده قرار گرفته یکم سخت میشه . به عبارت دیگه ، جواب دادن به این سوال که " آیا میتونیم فلان کد رو ویرایش یا حذف کنیم ، بدون اینکه منجر به خرابکاری برنامه بشه ؟" در این مدل نوشتن به مراتب سخت تر هست و این همون سوالی هست که موقع کدنویسی باید براش بهینه سازی انجام بدیم و به همین دلیله که استفاده از کامپوننت ها به متغیرهای سراسری ترجیح داده میشن .
از جمله دلایلی که میتونیم کامپوننت ها رو به متغیرهای سراسری ترجیح بدیم ، میتونیم به موارد زیر اشاره کنیم :
· کامپوننت ها بهمون کمک میکنن درمورد محلی که مقادیر ( اعم از توابع و آرایه ها و ورودی ها و ... ) مورد استفاده قرار میگیرن صریح تر عمل کنیم .
· با وجود کامپوننت ها ، پروسه تشخیص دادن اینکه تغییر در قسمتی از برنامه چه تاثیری روی قسمت های دیگه برنامه میزاره برامون ساده تر میشه .
· در این روش دنبال کردن مراحل ارسال و دریافت داده ها بصورت واضح مشخصه و فقط با دنبال کردن روند دریافت داده ها توسط کامپوننت ها ، میتونیم تغییرات احتمالی در برنامه مون رو پیش بینی کنیم .
البته اینها صرفا مزیت های Props Drilling بودن و اگر قرار باشه که با یک پروژه بزرگ دست و پنجه نرم کنیم ، قطعا استفاده از روش Props Drilling برای انتقال داده ها طاقت فرسا خواهد بود و ممکنه اتفاقاتی در برنامه مون رخ بده که هندل کردنشون برامون سخت و وقت گیر باشه ! به عنوان مثال :
· تغییر نام prop ها در میانه مسیر ارسال ها ، دنبال کردن prop ها رو برای ما سخت میکنه .
· تغییر شکل قالب بعضی از داده ها مثل داده ی زیر ، برامون مشکل ایجاد خواهد کرد :
· در میان انتقال props ها اگر کامپوننتی رو بنا به دلیلی حذف کنیم یا مکانی که درش ذخیره شده رو تغییر بدیم ، روند انتقال props ها با مشکل مواجه میشه .
خوب حالا که با همه ی این موارد آشنا شدیم ، بهتره که به پروژه مون برگردیم و یکمی هم دست به کد بشیم تا این موضوع رو بهتر درک کنیم :) البته اگر دقت کنیم متوجه میشیم که ما تا الان هم در برنامه مون به نحوی داشتیم از Props Drilling استفاده میکردیم ، به اینصورت که در کامپوننت App اومدیم personDelete و personChange رو به کامپوننت Persons انتقال دادیم و بعد personDelete و personChange رو از کامپوننت Persons به کامپوننت Person انتقال دادیم ( البته در این جا این مورد نیاز هم هست ، چراکه ما تو خود کامپوننت Person به idدسترسی نداریم ) ! اما به هر حال قبل از اینکه بخوایم با مفهوم Context Api در React آشنا بشیم ، میخوایم با یک مثال ساده مفهوم Props Drilling رو بهتر درک کنیم !
برای این منظور وارد فایل index.js میشیم و عنوان پروژه مون که "مدیریت کننده اشخاص" هست رو بصورت props به کامپوننت App انتقال میدیم :
سپس در پوشه ی Components یک پوشه جدید به نام Common و در داخل پوشه Common هم یک فایل جدید به نام Header.jsx ایجاد میکنیم ( کلاً بهتره یک پوشه بنام Common ایجاد کنیم و مواردی که مثل Header رایج هستن رو در داخلش قرار بدیم ) و بعد این دو قطعه کد که در فایل App.js قرار دارن رو انتخاب میکنیم :
و بعد اون هارو به اینصورت به داخل فایل Header.jsx انتقال میدیم :
سپس به اینصورت در داخل کامپوننت App از کامپوننت Header استفاده میکنیم ( توجه کنیم که عنوان پروژه مون رو هم به صورت props بهش پاس دادیم ) :
و نهایتاً در داخل کامپوننت Header به اینصورت از props ای که بهش انتقال دادیم استفاده میکنیم :
خوب ما در ابتدا اومدیم عنوان (title) پروژه مون رو از فایل index.js بصورت props به کامپوننت App انتقال دادیم و دیدیم که کامپوننت App بدون اینکه از این داده استفاده کنه ، فقط اون رو به عنوان props به کامپوننت Header پاس میده ، این موضوع دقیقا داره مفهوم Props Drilling رو بیان میکنه ! البته ما در اینجا مشکل خاصی نداریم ولی با توجه به دلایلی که در بالاتر گفته شد ، اگر پروژه مون بزرگ تر بشه ، قطعا استفاده از Prop Drilling طاقت فرسا خواهد بود و ممکنه که با دردسرهای مختلفی مواجه بشیم و اونموقع هست که دیگه این روش ، روش بهینه ای نخواهد بود و ناچارا برای ارسال یا به اشتراک گذاشتن داده هامون باید از روش های دیگه ای استفاده کنیم ! به همین دلیل قرار هست که در بخش بعدی با مفهوم Context Api آشنا بشیم :)