Lazy Loading و HOC Component
شناسه پست: 3519
بازدید: 700

در پست قبلی، ما به طور کامل محیط Redux را راه اندازی کرده و نمونه Axios را برای ارسال درخواستهای HTTP ایجاد کردیم. در ادامه، در این پست، ما قصد داریم Redux repository را داخل یک component ثبت کرده و از آن برای واکشی داده ها از سرور استفاده کنیم. علاوه بر این، ما می‌خواهیم component خود را به صورت lazy بارگذاری کنیم تا مزیت بارگذاری محتوا به طور lazy را نشان دهیم.

این مقاله، قسمتی از مجموعه آموزشی زیر میباشد:

اگر میخواهید تمام دستورالعملهای پایه و راهنمای کامل برای آموزش سریالی NET Core. را ببینید، به این لینک مراجعه کنید: دستورالعملهای کار با NET Core.

اگر میخواهید تمام دستورالعملهای پایه و راهنمای کامل برای آموزش سریالی React را ببینید، به این لینک مراجعه کنید: مقدمه معرفی آموزش سریالی React

برای بررسی قسمت قبل، به این لینک مراجعه کنید: HTTP, Axios, Redux

جهت دانلود سورس بر روی این لینک کلیک کنید: سری آموزشی React – قسمت 4

این پست به قسمتهای زیر تقسیم میشود:

ایجاد کامپوننت HOC ،OwnerList و Route ها

اجازه دهید ساختار پوشه ای زیر و فایل OwnerList.js را داخل پوشه containers ایجاد کنیم:

ساختار OwnerList

قبل از اصلاح کامپوننت OwnerList، بیایید یک higher-order component (HOC) (کامپوننت با order بالاتر) ایجاد کنیم. ما میخواهیم از آن در یک component، به عنوان یک helper برای wrap کردن محتوای خود داخل بلاک ()return استفاده کنیم. همانطور که (از پستهای قبلی) میدونید، بلاک ()return به یک تگ root و تمام محتوای داخل آن نیاز دارد. اگر نمی‌خواهیم از یک تگ div یا p که می‌تواند استایل‌های ما را خراب کند استفاده کنیم، می‌توانیم این component کمکی را ایجاد کنیم. این component یک wrapper ایجاد میکند که تمام محتوای children را بدون به هم ریختگی استایلهای یک پروژه برمیگرداند.

بنابراین داخل پوشه src، یک پوشه جدید ایجاد کنیم و نام آن را hoc بگذاریم. در این پوشه، میخواهیم یک پوشه جدید ایجاد کنیم و نام آن را Auxiliary بگذاریم. در آخر یک فایل جدید به نام Auxiliary.js ایجاد کنیم:

ساختار Auxiliary

حالا باید فایل Auxiliary.js را اصلاح کنیم:

تمام کاری که ما داریم اینجا انجام میدهیم فقط برگرداندن محتوای children است که بین تگ باز و بسته auxiliary قرار میگیرد.

حالا میتوانیم فایل OwnerList.js را اصلاح کنیم:

شرح کامپوننت OwnerList 

منطق پشت این کد کاملا ساده است.

ما اینجا یک آرایه خالی به نام owners ایجاد کرده ایم که قرار است تمام owner های درون دیتابیس را در خود نگه دارد. بالای جدول، یک link به کامپوننت Create وجود دارد. ما اینجا داریم از کامپوننت Link از کتابخانه react-router-dom استفاده میکنیم. سپس باید یک جدول ایجاد کنیم که تمام داده های درون آرایه را نشان دهد، اگرچه در حال حاضر، آن فقط یک آرایه خالی میباشد.

حالا بیایید فایل App.js را برای اضافه کردن یک route به این component اصلاح کنیم:

اگر اپلیکیشن خود را با دستور npm start اجرا کنیم، در نتیجه، می‌توانیم با کلیک کردن روی منوی Owner Actions به کامپوننت OwnerList برویم:

منوی OwnerActions

پیاده سازی Redux

از آنجایی که در حال حاضر، هیچ داده ای نداریم، اجازه دهید مقداری داده اضافه کنیم.

اول باید کامپوننت خود را به reducer خود متصل کنیم. reducer قرار است state را تنظیم کند و داده ها را به عنوان یک ویژگی در داخل آبجکت props به این component منتقل کند.

برای این منظور، connect را از کتابخانه react-redux وتمام action ها را از فایل repositoryAction.js ایمپورت کنیم:

سپس زیر براکت بسته کامپوننت خود و درست بالای دستور export، باید function های زیر را اضافه کنیم و سپس دستور export را تغییر دهیم:

تابع mapStateToProps ویژگی data را از آبجکت initialState از repositoryReducer به ویژگی data داخل کامپوننت OwnerList مپ میکند. برای دسترسی به این ویژگی data، فقط باید آن را به صورت this.props.data فراخوانی کنیم.

تابع mapDispatchToProps ویژگی اضافی onGetData را ایجاد میکند. ما ممکن است آن را با دستور this.props.onGetData فراخوانی کنیم. سپس این ویژگی، اکشن مورد نظر داخل فایل repositoryActions.js را dispatch میکند که این اکشن قرار است داده ها را از سرور واکشی کند.

جمع بندی Redux 

در حال حاضر اگر به نمودار پست قبلی نگاه کنیم، همه چیز کاملاً منطقی است. از این component، ما action داخل فایل repositoryActions.js را فراخوانی میکنیم. این action داده ها را از سرور واکشی کرده و reducer را trigger میکند. reducer ما با تغییر ویژگی data داخل آبجکت state ،initialState را آپدیت میکند. در آخر، Central Store، این ویژگی data را با تابع mapStateToProps به این component مپ میکند.

ایجاد کامپوننت Owner

چون ما میخواهیم چند owner را داخل کامپوننت OwnerList نمایش دهیم، بیایید کامپوننت Owner را ایجاد کرده و آن را به داخل کامپوننت OwnerList ایمپورت کنیم.

در پوشه components ساختار زیر را ایجاد کنید:

Owner Component

برای کار با تاریخها، باید یک کتابخانه third-party دیگر به نام react-moment را نصب کنیم:

نصب React-moment

کتابخانه moment را نیز باید نصب کنیم:

حالا میتوانیم فایل Owner.js را اصلاح کنیم:

در این child component، ما داده های owner را از طریق آبجکت props دریافت میکنیم. سپس یک row به همراه داده ها و چند دکمه برای رفتن به component های مختلف ایجاد میکنیم. همه دکمه ها، تابع های ارجاعی هستند که redirect به سمت کامپوننتهای details، update و delete را امکان پذیر میکنند.

نکته مهمی که باید به آن توجه کرد این است که آبجکت props دارای ویژگی “history” است که به ما این امکان را می دهد که به صورت برنامه ریزی شده navigate کنیم. علاوه بر این، ما اینجا از قالب تاریخ استفاده کرده ایم: “DD/MM/YYYY” فقط برای اینکه نشان دهیم کار با فرمت ها با استفاده از کتابخانه Moment چقدر آسان است. برای کامپوننتهای create و update، از قالب  “MM/DD/YYYY” استفاده خواهیم کرد. تنها کاری که باید انجام دهید این است که این کامپوننت را در کامپوننت OwnerList ایمپورت کنید و تمام owner ها را روی صفحه نمایش دهید.

نمایش نتایج Owners

کامپوننت Owner را داخل کامپوننت OwnerList ایمپورت کنید:

سپس بالای قسمت ()render، قصد داریم یک function جدید ایجاد کنیم. با این function، قصد داریم ویژگی OnGetData را برای واکشی داده ها از سرور فراخوانی کنیم:

componentDidMount یک  lifecycle hook است و به محض رندر شدن component فراخوانی میشود.

در آخر، داخل render function، کد زیر را برای پر کردن آرایه  “owners” خود اضافه کنید:

در این function، بررسی میکنیم که آیا ویژگی data پر شده است یا خیر (زیرا درخواستهای http، درخواستهای async هستند) و اینکه آیا یک آرایه است یا خیر. سپس برای هریک از عنصرهای این آرایه، ما کامپوننت Owner را با داده ها پر میکنیم. به ویژگی key که هنگام ایجاد component های فرزند از آرایه آبجکتها الزامی است توجه کنید. علاوه بر این، آبجکت props را پاس می دهیم تا به ویژگی “history” آن آبجکت دسترسی داشته باشیم. به همین ترتیب، یک آبجکت واحد owner را به child component می‌فرستیم زیرا می‌خواهیم این child component بتواند از دستور props.owner استفاده کند.

عالی.

حالا اگر بخواهیم به منوی Owner Actions برویم، نتیجه را با owner های زیر خواهیم دید:

نمایش OwnersList

بارگزاری محتوا به صورت Lazy

تا به حال، ما کامپوننت OwnerList خود را بلافاصله بارگذاری می کردیم و نه به صورت تنبل (lazy)، به این معنی که پس از شروع برنامه، همه منابع نیز بلافاصله بارگیری می شوند. این بهترین شیوه نیست زیرا ممکن است کاربر هرگز از صفحه Owner Actions بازدید نکند، بنابراین منابع این صفحه نیز نباید بارگیری شوند.

بیایید پروژه خود را اصلاح کنیم تا بتوانیم از ویژگی بارگذاری تنبل (lazy loading) استفاده کنیم.

بیایید در داخل پوشه hoc، یک پوشه جدید به نام AsyncComponent و داخل این پوشه، یک فایل جدید به نام AsyncComponent.js ایجاد کنیم و آن را تغییر دهیم:

با این کامپوننت، کامپوننت خود را به صورت ناهمگام (async) بارگذاری می کنیم.

برای کامل کردن این action، ما باید فایل App.js را برای بارگزاری کامپوننت OwnerList  خود در async mode اصلاح کنیم:

حالا اینجا ما کامپوننت Async خود را import میکنیم و داخل آن، کامپوننت OwnerList خود را import میکنیم. در آخر، ما OwnerList را دیگر داخل کامپوننت Route بارگزاری نمیکنیم، در صورتی که به جای آن، AsyncOwnerList را بارگزاری میکنیم.

اکنون اگر پس از restart کردن برنامه خود به صفحه Owner Actions بروید، فایل اضافی دیگری به نام chunk را مشاهده خواهید کرد که فقط برای این صفحه بارگذاری شده است.

LazyLoading در React

نتیجه گیری

با خواندن این پست، شما موارد زیررا یاد گرفتید:

  • شیوه ایجاد کامپوننتهای HOC
  • نحوه پیاده سازی Redux برای واکشی داده ها از سرور
  • نحوه استفاده از کتابخانه Moment برای قالب بندی تاریخها
  • شیوه بارگزاری component ها به شیوه async با استفاده از ویژگی Lazy Loading

بابت خواندن این مقاله از شما تشکر میکنیم و امیدواریم که برای شما مفید واقع قرار گرفته باشد.

در قسمت بعدی این سری از آموزش، قصد داریم نحوه handle کردن خطاها در حین ارسال درخواستهای HTTP را یاد بگیریم.

نویسنده

امید عباسی
من امید عباسی هستم. سالهاست که در زمینه برنامه نویسی با تکنولوژی دات نت فعالیت میکنم و عاشق این هستم که تجربیات و دانش خودم را در این زمینه با دیگران به اشتراک بزارم. خیلی دوست دارم که نظر و انتقاد خودتون رو در مورد این نوشته برای من بنویسید تا بتونم در آینده، مطالب بهتر و ارزشمندتری را برای شما فراهم کنم. در صورت داشتن هرگونه سوال هم در قسمت دیدگاه ها میتونید با بنده در ارتباط باشید