ریداکس چیست ؟ آموزش ریداکس در ریکت و بررسی تخصصی Redux در ری اکت !

کتابخانه ریداکس یکی از محبوب ترین کتابخانه های جاوااسکریپتی هست که توسط طیف بزرگی از برنامه نویس ها و توسعه دهنده ها در حال استفادس ? ریداکس در ریکت هم محبوبیت خیلی خیلی بالایی داره و بطور گسترده داره استفاده میشه!تو این مقاله میخوایم بصورت 0 تا 100 ریداکس و ریداکس در ری اکت رو بررسی کنیم ( البته به زبان ساده !! ) و ببینیم چه کاربرد، مزایا و معایبی داره و چطور باید از Redux در ری اکت استفاده کنیم ؟!پس با فرانت اندی همراه باشید ?ریداکس چیست ؟وقتی به وبسایت اصلی کتابخانه Redux مراجعه کردم تا ببینم redux چیست، دیدم ریداکس خودشو اینطوری معرفی کرده :اما بریم ببینیم معنی این جمله چیه ؟ریداکس یک کتابخانه مدیریت State هست ( State Management ) که تو تمام کتابخانه ها و فریمورک های جاوا اسکریپتی قابلیت استفاده داره. معروف ترین کتابخانه ها و فریمورک هایی که از ریداکس میشه داخلشون استفاده کرد عبارتند از :ریداکس در ویو ریداکس در ریکتریداکس در انگولاردرک مفاهیم پایه ی کتابخانه Redux خیلی خیلی مهمه و ما به عنوان یک Front-End Developer باید این مفاهیم پایه و اساسی ریداکس رو یاد بگیریم.به کمک کتابخانه ریداکس، میتونیم تمامی State های اپیکیشن خودمون رو داخل جایی به اسم Store ذخیره کنیم و هرزمان که به اون State داشتیم، از Store بخونیمش.مثلا میتونیم نام کاربر، محصولات سبد خرید، تنظیمات پروفایل، زبان سایت، دارک مود و … رو داخل Store در ریداکس ذخیره کنیم و هرجایی که به این اطلاعات احتیاج پیدا کردیم، از Store در ریداکس بخونیمش.چرا باید از ریداکس استفاده کنیم ؟ریداکس به ما اجازه میده تمام State های اپیکیشن خودمون رو در یک بخش ذخیره و مدیریت کنیم ( Store ) و همین موضوع باعث میشه که اپیکیشن ما قابل پیش بینی و کنترل شده باشه.البته ریداکس صرفا شامل مزایا نیست و معایبی هم داره. خیلی از توسعه دهنده ها کتابخانه ریداکس رو پیشنهاد نمیکنن چون ریداکس پیچیدگی زیادی داره.بیاید یک سناریو رو در نظر بگیریم تا به دلیل نیاز به Redux پی ببریم ..به تصویر زیر دقت کنید :تصویر بالا نشون میده که چطور تو کتابخانه ری اکت میتونیم اطلاعات رو از کامپوننت والد، به کامپوننت های فرزند منتقل کنیم (به کمک Props)تو تصویر بالا نیازی به ریداکس نداریم!ولی به تصویر زیر دقت کنید :اگه تو کامپوننت D و C به یکسری اطلاعات مشترک احتیاج داشته باشیم، باید چیکار کنیم ؟؟منطقا باید این State مشترک رو تو اولین کامپوننت والد مشترک ذخیره کنیم و سپس این State رو به کمک Props به کامپوننت C و D منتقل کنیم.اما اینجا 2 مشکل بزرگ وجود داره ! ! !اول از همه اینکه تو کامپوننت A و B به این State نیازی نداشتیم ولی چون میخواستیم State رو به کامپوننت C و D برسونیم، از کامپوننت A و B هم عبورشون دادیم.دوم مشکل این هست که اگه State ما تغییر کنه، تمامی کامپوننت های ما re-render میشن و این صادقانه افتضاحه !راه حل Redux در ری اکت هست. چون State مشترک مارو در یک مکان جداگانه ( اسمش Store هست ) ذخیره میکنه و دیگه نیازی نیست State رو بین کامپوننت ها عبور بدیم.تو تصویر زیر، این موضوع کاملا واضحه :چه زمانی از کتابخانه ریداکس استفاده کنیم ؟ساده ترین پاسخی که میشه به این سوال داد، این هست که خودتون نیاز به کتابخانه Redux رو حس میکنید! همه ی ما بطور پیشفرض از State Management های پیشفرض استفاده میکنیم ( مثل useState و useContext )ولی با بزرگتر شدن اپیکیشن ما، دیگه این State Management ها پاسخگو نیستن و کارایی ندارن. چنین مواقعی باید به سمت State Management های پیشرفته تر مثل کتابخانه ریداکس بریم.کاربرد ریداکس چیست ؟کتابخانه ریداکس یک State Menagement قدرتمند هست که داده های اپیکیشن مارو ( state ) ذخیره، نگهداری و مدیریت میکنه.ما از ریداکس در ری اکت و هر کتابخانه ی جاوا اسکریپتی دیگه ای میتونیم استفاده کنیم.زمانیکه اپیکیشن ما بزرگ و بزرگتر میشه، ما نیاز داریم که یکسری از state های خودمون رو در یک بخش مجزا ذخیره کنیم ( نه داخل خود کامپوننت به کمک useState ) و این state ذخیره شده در یک بخش مجزا رو بین چندین کامپوننت مختلف به اشتراک بزاریم.به این بخش مجزا در ریداکس، Store میگیم.سناریویی رو در نظر بگیرید که به اطلاعات کاربر، در 8 کامپوننت مختلف احتیاج داریم ( پروفایل، هدر، سبد خرید، صفحه محصول و .. )در چنین حالتی منطقی نیست که اطلاعات کاربر رو در تمامی این 8 کامپوننت ذخیره کنیم! چون اگر اطلاعات کاربر تغییر پیدا کنه، مجددا باید تمامی این 8 بخش رو تغییر بدیم.بهترین و منطقی ترین راه حل برای چنین سناریویی استفاده از کتابخانه هایی نظیر ریداکس هست که یک State مشخص رو برای ما در یک بخش جداگانه ( نه داخل خود کامپوننت ها ) ذخیره میکنه ( به این بخش که اطلاعات داخلش ذخیره میشه Store میگیم ) و این اطلاعات رو بین تمامی کامپوننت ها به اشتراک میزاره.حالا اگه نیاز باشه که این اطلاعات تغییر پیدا کنه، فقط کافیه این اطلاعات از داخل Store تغییر پیدا کنه. ( نه از داخل تمامی کامپوننت ها )ما میتونیم State های کامپوننت های خودمون رو بین همدیگه به اشتراک بزاریم.اینکه میگیم ریداکس قابل پیش بینیه یعنی چی ؟دیدیم که ریداکس خودش رو A Predictable State Container For Js App معرفی کرده. تو این جمله اشاره کرده که ریداکس یک کتابخانه ی قابل پیش بینی برای مدیریت State اپیکیشن های جاوا اسکریپتیه.اما بریم ببینیم منظور از “قابل پیش بینی” چی هست ؟تو ریداکس، State ها صرفا خواندنی هستن ( Read-only )برای اینکه بتونیم State های خودمون تو ریداکس رو آپدیت کنیم، باید یک Action بفرستیم و تو این Action توضیح بدیم که چه تغییری روی این State، ما نیاز داریم ؟به همین دلیل که برای بروزرسانی State های خودمون توضیح میدیم، اپیکیشن ما قابل پیشبینی ( Predictable ) میشهریداکس در ری اکت !ریداکس یک کتابخانه جاوا اسکریپتیه و قابلیت استفاده در هر فریمورک یا کتابخانه جاوا اسکریپتی رو داره .redux در ری اکت خیلی محبوب و پرطرفداره ! همین الان که من دارم این مقاله رو مینویسم، کتابخانه react-redux بیشتر از 7 میلیون دانلود هفتگی داره!این یعنی Redux در ری اکت بشدت پرطرفداره و Comminuty خوبی داره.معمولا از ریداکس در ری اکت زمانی کمک میگیریم که اپیکیشن ما بزرگه یا قراره در آینده بزرگ بشه. این یعنی در اپیکیشن های کوچک ری اکتی هیچ نیازی به ریداکس در ریکت نداریم.ما میتونیم از ریداکس در ریکت استفاده کنیم و مدیریت State های اپیکیشن خودمون رو به Redux در ریکت بسپاریم!زمانیکه اپیکیشن ری اکتی ما بزرگ میشه و مدیریت State در اون پیچیده میشه، Redux در ری اکت انتخاب معقولانه و منطقی هست.ریداکس ! یک State Management قدرتمند !مدیریت State در اپیکیشن های بزرگ همیشه چالش برانگیز بوده. ابزار های State Management زیادی وجود دارن که وظیفه نگهداری، مدیریت و به اشتراک گذاری State های مارو بین کامپوننت ها به عهده میگیرن.از بین State Management هایی که وجود داره، Redux یکی از قدرتمندترین اونهاست ! ریداکس در ریکت هم خیلی محبوبه و پر استفاده ترین کتابخانه ی State Management هست.فرض کنید در یک کامپوننت یک State داریم و میخواهیم این State را به کامپوننتی منتقل کنیم که فرزند و یا حتی والد کامپوننت ما نیست ! چون کامپوننت مقصد تو یک درخت جداگانه وجود داره.در چنین مواقعی باید از ابزار های State Management مثل ریداکس کمک بگیریم.ریداکس چطور کار میکنه ؟تا الان یکسری توضیحات در مورد کتابخانه ریداکس شنیدیم و متوجه شدیم که ریداکس چیست !حالا وقتشه که ببینیم ریداکس چطوری کار میکنه ؟!روش کار ریداکس خیلی سادس ! اما معمولا پیچیده مطرح میشه و به همین خاطر فکر میکنیم ریداکس سخته !بریم ببینیم روش کار ریداکس چجوریه ..ریداکس از 3 مفهوم اصلی تشکیل شده :StoreActionReducerمفهوم Store در ریداکس چیست ؟تو کتابخانه ریداکس، ما تمامی State های خودمون رو داخل یک جایی ذخیره میکنیم که بهش Store میگیم.بعدا میتونیم به State های ذخیره شده در Store از هر کامپوننتی دسترسی داشته باشیم ( نه مثل Props در ریکت که باید State رو از هر کامپوننت به کامپوننت دیگه منتقلش میکردیم تا به مقصد برسه )در واقع Store یک Object جاوا اسکریپتی هست و شامل تمامی State هایی هست که ما داخلش ذخیره کردیم.خود Store رو میشه به عنوان یک container در نظر گرفت چون دور کل اپیکیشن پیچیده میشه تا از تمامی بخش های اپیکیشن ( تمامی کامپوننت ها ) بتونیم به State های ذخیره شده در Store دسترسی داشته باشیم.ما از داخل هر کامپوننتی میتونیم به store دسترسی داشته باشیم و مقدار ذخیره شده داخل store رو بخونیم، ویرایش کنیم یا حذف کنیم.تنها راهی که میتونیم State های موجود در Store رو ویرایش کنیم، Action هست که تو پاراگراف بعدی بررسیش میکنیم…( مثل setState که تو هوک useState ازش استفاده میکردیم تا بتونیم state خودمون رو بروزرسانی کنیم )فقط یک Store توی اپیکیشن خودتون داشته باشید! توی هر اپیکیشن میشه یک یا چند Store ساخت و ازش استفاده کرد اما اکیدا پیشنهاد میشه فقط یک Store بسازید.مفهوم Action در ریداکس چیست ؟درحقیقت Action در ریداکس در واقع نوعی event ( رویداد ) هست. تنها راهی که میتونیم State و داده های خودمون رو داخل Store ذخیره یا بروزرسانی کنیم، Action هست.خود Action یک Object جاوا اسکریپتیه که از 2 بخش زیر تشکیل شده :Type :هر اکشن یک type داره. type مشخص میکنه که event ما قراره چه کاری انجام بده. مثلا اگه قراره تو عملیات بروزرسانی State در ریداکس، یک کاربر جدید اضافه کنیم، میتونیم تایپِ اکشنِ خودمون رو add_user بزاریم.همچنین اگه قراره کاربر رو از Store موجود در ریداکس حذف کنیم، میتونیم type اکشن خودمون رو remove_user بزاریم.منطقا مقداری که برای type در نظر میگیریم باید مشخص کننده نوع کاری باشه که میخوایم انجامش بدیم. این مقدار هرچیزی میتونه باشه فقط باید مشخص کننده وظیفه ی action باشه.Payload :این مقدار اختیاریه و میتونه داخل Action وجود داشته باشه یا وجود نداشته باشه.درکل Payload در Action شامل اطلاعاتی هست که برای ذخیره یا بروزرسانی State موجود در Store بهش نیاز داریم.برفرض ما قصد ذخیره کردن کاربر Login شده رو داخل Store داریم. در این سناریو مقدار Payload باید شامل اطلاعات کاربر باشه مثل : نام کاربر، فامیل، شماره تلفن، کدملی و ..تو این سناریو مقدار Type این Action میتونه ADD_USER باشه.خود Payload یک Object جاوا اسکریپتیه.در برخی موارد نیازی به اضافه کردن payload در action نداریم. مثلا یک action وظیفه ی حذف اطلاعات تمامی کاربران از store رو داره . در این سناریو دیگه هیچ payload نداریم و صرفا باید type اکشن رو مشخص کنیم.کاربرد actions در Redux چیست ؟بریم ببینیم کاربرد action در ریداکس چیست ؟همونطور که گفتیم، برای اینکه بتونیم یک State رو داخل Store ذخیره یا بروزرسانی کنیم، نیاز به یک Action داریم.بدون Action نمیتونیم State خودمون رو داخل Store ذخیره یا بروزرسانی کنیم!!زمانیکه Action خودمون رو ساختیم، میتونیم به کمک متود dispatch ، اکشن خودمون رو به Store بفرستیم.یک نمونه action در ریداکسبرای اینکه بهتر بتونیم action در ریداکس رو درک کنیم، بیاید یک مثال واقعی رو مرور کنیم تا ببینیم action در ریداکس چیست ؟فرض کنید ما یک اپیکیشن Counter ( شمارنده ) داریم که شامل یک دکمه برای افزایش عدد و یک دکمه برای کاهش عدد هست. عدد فعلی داخل Store در ریداکس ذخیره میشه.تو این سناریو 2 اکشن داریم :INCREMENTDECEREMENTاکشن INCREMENT برای افزایش عدد کاربرد داره و اکشن DECEREMENT برای کاهش عدد.تو تصویر زیر میشه پروسه مشخص شده :زمانیکه کاربر روی دکمه “افزایش عدد” کلیک میکنه ما باید اکشنِ INCREMENT رو به کمک متود dispatch به Store خودمون بفرستیم. اینجوری عدد ذخیره شده در Store ، افزایش پیدا میکنه.در واقع action ما که INCREMENT نام داشت، بصورت زیر هست:{ type: &quotINCREMENT&quot, payload: { count: 1, } }ما به کمک action بالا میتونیم مقدار ذخیره شده در Store رو اضافه کنیم. اگه به payload دقت کنید میبینید که داخلش مقدار استاتیک ( ثابت ) 1 قرار داده شده . و این خوب نیست!خیلی جاها نیازه که مقدار داینامیک رو داخل action خودمون قرار بدیم. در چنین شرایطی به Action Creator نیاز داریم.اما Action Creator در Redux چیست ؟Action Creator در ریداکس یک تابع هست که برای ما یک Action میسازه ( return میکنه )به مثال زیر که یک action creator هست دقت کنید:const IncrementActionCreator = (countForIncrement) => { return { type: &quotINCREMENT&quot, payload: { count: countForIncrement, } } }تو تیکه کد بالا یک action creator داریم که یک تابع هست. این تابع مقدار داینامیک رو از طریق آرگومان ورودی میگیره و برای ما یک Action برمیگردونه.مزیت Action Creator این هست که میتونیم مقادیر داینامیک خودمون رو داخل Action خودمون جا بدیم. ولی گاهی اوغات که مقادیر داینامیک نداریم و اکشن ما میتونه استاتیک باشه، نیازی به Action Creator در redux نداریم.مفهوم reducer در ریداکس چیست ؟سومین و آخرین مفهوم اصلی در ریداکس، Reducer هست. پس بریم ببینیم Reducer در Redux چیست ؟reducer در ریداکس یک Pure Function هست که از ما مقدار فعلی State رو میگیره، action رو به Store میفرسته و مقدار جدید state رو به ما برمیگردونه.تو تصویر زیر میشه کاربرد Reducer در ریداکس رو دید :همونطور که گفتیم تابع reducer از ما مقدار فعلی state و یک action میگیره و مقدار جدید state رو به ما برمیگردونه.تیکه کد زیر یک reducer در redux هست که اسمش رو CounterReducer گذاشتیم :const CounterReducer = (state = initialState, action) => { switch (action.type) { case &quotINCREMENT&quot: return state + action.incrementBy ? action.incrementBy : 1 default: return state; } };تو تیکه کد بالا یک reducer داریم که وظیفه بروزرسانی State قبلی ما که داخل Store هست رو داره.داخل تابع reducer از یک switch استفاده کردیم که در حال حاضر فقط تایپ INCREMENT (برای اضافه کردن عدد)رو هندل میکنه اما ما میتونیم تایپ های بیشتری به این reducer اضافه کنیم ( مثل DECEREMENT و .. )اگه ما یک Action با تایپ INCREMENT صدا بزنیم ( dispatch کنیم ) باعث میشه که خط 4 تیکه کد بالا اجرا بشه و مقدار جدید + مقدار فعلی بشه و مقدار جدید return بشه.اگه ما داخل action خودمون payload قرار داده باشیم ، مقدار موجود در payload + مقدار قبلی state میشه. و درصورتیکه هیچ payload برای اکشن خودمون مشخص نکرده باشیم، مقدار پیشفرض 1 + مقدار فعلی state میشه.در حقیقت تابع Reducer از ما مقدار قبلی state ، رو میگیره و بر اساس نوع اکشنی که بهش ارسال شده ( مثل INCREMENT ) مقدار جدید state رو بهمون برمیگردونه.زمانیکه ما یک Action رو dispatch میکنیم تا Store ما آپدیت بشه، به محض دریافت state جدید کامپوننت ما re-render میشه.ما گفتیم که Reducer از ما State فعلی و یک Action دریافت میکنه و یک State جدید تحویل میده!تو تصویر زیر میشه این موضوع رو کاملا متوجه شد :ابزار Redux toolkit چیست ؟خود ریداکس یک State Management فوق العادس اما میتونه حجم زیادی از اضافه کاری و پیچیدگی رو به اپیکیشن ما اضافه کنه.به همین دلیل به هرکسی که از ریداکس در ری اکت استفاده میکنه، پیشنهاد میشه که از Redux Toolkit در ریداکس استفاده کنه.ریداکس تولکیت تمامی پروسه هایی که تو ریداکس داریم رو برای ما راحت تر میکنه.ریداکس تولکیت شامل مجموعه ای از ابزار ها و توابع هست که کمک میکنه خیلی ساده تر و راحت تر بتونیم با ریداکس کار کنیم! در حقیقت تو Redux Toolkit از اضافه گویی و موارد اضافی که تو ریداکس خام داشتیم، پرهیز میکنیم.استفاده از ریداکس تولکیت باعث میشه حجم کد کمتری بنویسیم و استفاده از کتابخانه ریداکس، آسونتر بشه.همه ی این موارد باعث میشه که بتونیم تو زمان و انرژی خودمون صرفه جویی کنیم و با موارد اضافی که تو نسخه خام ریداکس داشتیم، خداحافظی کنیم:)Redux Toolkit صرفا برای ریداکس در ری اکت کاربرد نداره و قابلیت استفاده با هر فریمورک و کتابخانه جاوا اسکریپتی دیگه مثل vue.js رو هم داره. مثلا ما میتونیم از ریداکس در Angular هم استفاده کنیم.بریم ببینیم مزایای Redux Toolkit در ریداکس چیه ؟ساخت Store در ریداکس به کمک Redux Toolkitلطفا برای مطالعه ادامه این مقاله در وبسایت فِرانت اِندی + مثالهای بیشتر روی لینک زیر کلیک کنید:ریداکس در ری اکت