ریداکس چیست ؟ آموزش ریداکس در ریکت و بررسی تخصصی 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 های کامپوننت های خودمون رو بین همدیگه به اشتراک بزاریم.
اینکه میگیم ریداکس قابل پیش بینیه یعنی چی ؟
اما بریم ببینیم منظور از “قابل پیش بینی” چی هست ؟
تو ریداکس، State ها صرفا خواندنی هستن ( Read-only )
برای اینکه بتونیم State های خودمون تو ریداکس رو آپدیت کنیم، باید یک Action بفرستیم و تو این Action توضیح بدیم که چه تغییری روی این State، ما نیاز داریم ؟
به همین دلیل که برای بروزرسانی State های خودمون توضیح میدیم، اپیکیشن ما قابل پیشبینی ( Predictable ) میشه.
ریداکس در ری اکت !
ریداکس یک کتابخانه جاوا اسکریپتیه و قابلیت استفاده در هر فریمورک یا کتابخانه جاوا اسکریپتی رو داره .
redux در ری اکت خیلی محبوب و پرطرفداره ! همین الان که من دارم این مقاله رو مینویسم، کتابخانه react-redux بیشتر از 7 میلیون دانلود هفتگی داره!
این یعنی Redux در ری اکت بشدت پرطرفداره و Comminuty خوبی داره.
معمولا از ریداکس در ری اکت زمانی کمک میگیریم که اپیکیشن ما بزرگه یا قراره در آینده بزرگ بشه. این یعنی در اپیکیشن های کوچک ری اکتی هیچ نیازی به ریداکس در ریکت نداریم.
زمانیکه اپیکیشن ری اکتی ما بزرگ میشه و مدیریت State در اون پیچیده میشه، Redux در ری اکت انتخاب معقولانه و منطقی هست.
ریداکس ! یک State Management قدرتمند !
مدیریت State در اپیکیشن های بزرگ همیشه چالش برانگیز بوده. ابزار های State Management زیادی وجود دارن که وظیفه نگهداری، مدیریت و به اشتراک گذاری State های مارو بین کامپوننت ها به عهده میگیرن.
از بین State Management هایی که وجود داره، Redux یکی از قدرتمندترین اونهاست ! ریداکس در ریکت هم خیلی محبوبه و پر استفاده ترین کتابخانه ی State Management هست.
فرض کنید در یک کامپوننت یک State داریم و میخواهیم این State را به کامپوننتی منتقل کنیم که فرزند و یا حتی والد کامپوننت ما نیست ! چون کامپوننت مقصد تو یک درخت جداگانه وجود داره.
در چنین مواقعی باید از ابزار های State Management مثل ریداکس کمک بگیریم.
ریداکس چطور کار میکنه ؟
روش کار ریداکس خیلی سادس ! اما معمولا پیچیده مطرح میشه و به همین خاطر فکر میکنیم ریداکس سخته !
بریم ببینیم روش کار ریداکس چجوریه ..
ریداکس از 3 مفهوم اصلی تشکیل شده :
Reducer
Action
Store
Store در ریداکس چیست ؟
تو کتابخانه ریداکس، ما تمامی State های خودمون رو داخل یک جایی ذخیره میکنیم که بهش Store میگیم.
بعدا میتونیم به State های ذخیره شده در Store از هر کامپوننتی دسترسی داشته باشیم ( نه مثل Props در ریکت که باید State رو از هر کامپوننت به کامپوننت دیگه منتقلش میکردیم تا به مقصد برسه )
در واقع Store یک Object جاوا اسکریپتی هست و شامل تمامی State هایی هست که ما داخلش ذخیره کردیم.
خود Store رو میشه به عنوان یک container در نظر گرفت چون دور کل اپیکیشن پیچیده میشه تا از تمامی بخش های اپیکیشن ( تمامی کامپوننت ها ) بتونیم به State های ذخیره شده در Store دسترسی داشته باشیم.
ما از داخل هر کامپوننتی میتونیم به store دسترسی داشته باشیم و مقدار ذخیره شده داخل store رو بخونیم، ویرایش کنیم یا حذف کنیم.
تنها راهی که میتونیم State های موجود در Store رو ویرایش کنیم، Action هست که تو پاراگراف بعدی بررسیش میکنیم…
( مثل setState که تو هوک useState ازش استفاده میکردیم تا بتونیم state خودمون رو بروزرسانی کنیم )
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 خودمون رو ساختیم، میتونیم به کمک متود dispatch ، اکشن خودمون رو به Store بفرستیم.
یک نمونه action در ریداکس
برای اینکه بهتر بتونیم action در ریداکس رو درک کنیم، بیاید یک مثال واقعی رو مرور کنیم تا ببینیم action در ریداکس چیست ؟
فرض کنید ما یک اپیکیشن Counter ( شمارنده ) داریم که شامل یک دکمه برای افزایش عدد و یک دکمه برای کاهش عدد هست. عدد فعلی داخل Store در ریداکس ذخیره میشه.
تو این سناریو 2 اکشن داریم :
- INCREMENT
- DECEREMENT
اکشن INCREMENT برای افزایش عدد کاربرد داره و اکشن DECEREMENT برای کاهش عدد.
تو تصویر زیر میشه پروسه مشخص شده :
زمانیکه کاربر روی دکمه “افزایش عدد” کلیک میکنه ما باید اکشنِ INCREMENT رو به کمک متود dispatch به Store خودمون بفرستیم. اینجوری عدد ذخیره شده در Store ، افزایش پیدا میکنه.
در واقع action ما که INCREMENT نام داشت، بصورت زیر هست:
{
type: "INCREMENT",
payload: {
count: 1,
}
}
ما به کمک action بالا میتونیم مقدار ذخیره شده در Store رو اضافه کنیم. اگه به payload دقت کنید میبینید که داخلش مقدار استاتیک ( ثابت ) 1 قرار داده شده . و این خوب نیست!
خیلی جاها نیازه که مقدار داینامیک رو داخل action خودمون قرار بدیم. در چنین شرایطی به Action Creator نیاز داریم.
اما Action Creator در Redux چیست ؟
Action Creator در ریداکس یک تابع هست که برای ما یک Action میسازه ( return میکنه )
به مثال زیر که یک action creator هست دقت کنید:
const IncrementActionCreator = (countForIncrement) => {
return {
type: "INCREMENT",
payload: {
count: countForIncrement,
}
}
}
تو تیکه کد بالا یک action creator داریم که یک تابع هست. این تابع مقدار داینامیک رو از طریق آرگومان ورودی میگیره و برای ما یک Action برمیگردونه.
مزیت Action Creator این هست که میتونیم مقادیر داینامیک خودمون رو داخل Action خودمون جا بدیم. ولی گاهی اوغات که مقادیر داینامیک نداریم و اکشن ما میتونه استاتیک باشه، نیازی به Action Creator در redux نداریم.
reducer در ریداکس چیست ؟
reducer در ریداکس یک Pure Function هست که از ما مقدار فعلی State رو میگیره، action رو به Store میفرسته و مقدار جدید state رو به ما برمیگردونه.
تو تصویر زیر میشه کاربرد Reducer در ریداکس رو دید :
همونطور که گفتیم تابع reducer از ما مقدار فعلی state و یک action میگیره و مقدار جدید state رو به ما برمیگردونه.
تیکه کد زیر یک reducer در redux هست که اسمش رو CounterReducer گذاشتیم :
const CounterReducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENT":
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
ما میتونیم بدون Redux Toolkit تو اپیکیشن خودمون Store داشته باشیم اما صادقانه خیلی پیچیدگی و اضافه کاری داره برامون.
اگه از ریداکس تولکیت استفاده کرده باشیم، میتونیم خیلی راحت تر Store در ریداکس بسازیم.
به کمک تابع configureStore خیلی ساده و راحت میتونیم Store بسازیم.
تو مثال زیر ما برای اپیکیشن خودمون که یک شمارنده ( counter ) هست یک Store ساختیم:
import { configureStore } from '@reduxjs/toolkit' // این تابع برای ما استور میسازه
import counterReducer from './counterReducer' // اینجا ردیوسر خودمون رو فراخوانی کردیم
const store = configureStore({
reducer: {
counter: counterReducer, // در اینجا ردیوسر خودمون رو به استور معرفی کردیم
},
})
export default store
همونطور که تو تیکه کد بالا مشخصه، Redux Toolkit خیلی راحت برای ما Store میسازه.
فقط کافیه از تابع configureStore در ریداکس تولکیت استفاده کنیم و Reducer هایی که قبلا ساختیم رو به Store معرفی کنیم.
ساخت action در ریداکس به کمک Redux Toolkit
تو کتابخانه ریداکس خیلی راحت میتونیم action بسازیم. مخصوصا اگه از Redux Toolkit استفاده کرده باشیم!
همونطور که قبلا هم اشاره کردیم، یک action یک Object جاوااسکریپتیه که شامل type و payload هست.
ما میتونیم به کمک تابع createAction در ریداکس یک action بسازیم.
فقط کافیه آرگومان های ورودی مورد نیاز برای ساخت action در ریداکس رو بهش پاس بدیم ( type , payload ) .
خروجی createAction، یک تابع هست که هر زمان صداش بزنیم، action ما dispatch میشه.
به مثال زیر توجه کنید :
const todoAdd = createAction('INCREMENT')
todoAdd({ value: 2 })
// {type : "INCREMENT", payload : {value : 2}})
تو خط 1 تیکه کد بالا یک action ساختیم که اسمش todoAdd هست. اینکار رو به کمک تابع createAction در redux toolkit کردیم.
آرگومان ورودی createAction ، نوع اکشن ( type ) هست که بهش INCREMENT رو دادیم.
ما هر زمانی که احتیاج داشتیم میتونیم todoAdd رو صدا بزنیم تا مقدار todo ما افزایش پیدا کنه.
خود todoAdd که action ما هست یک ورودی از ما میگیره که payload اکشن ماست.
ما بهش مقدار 2 رو به عنوان payload دادیم.
ساخت reducer در ریداکس به کمک Redux Toolkit
وظیفه reducer در ریداکس این هست که باتوجه به نوع اکشنی که بهش پاس دادیم ( action type ) و مقادیری که بهش پاس دادیم ( action payload ) مقدار state رو تغییر بده و state جدید رو به ما برگردونه.
داخل تابع reducer میتونیم به کمک switch بررسی کنیم که کدوم action type رو براش فرستادیم.
ریداکس تولکیت ویژگی createReducer رو در اختیار ما گذاشته تا بتونیم به کمک این ویژگی reducer بسازیم.
تو مثال زیر 2 اکشن ساختیم ( به کمک createAction و یک reducer ( به کمک createReducer ) :
import { createAction, createReducer } from '@reduxjs/toolkit'
const increment = createAction('counter/increment')
const incrementByAmount = createAction('counter/incrementByAmount')
const initialState = { value: 0 }
const counterReducer = createReducer(initialState, (builder) => {
builder
.addCase(increment, (state, action) => {
state.value++
})
.addCase(incrementByAmount, (state, action) => {
state.value += action.payload
})
})
تو خط 3 و 4 دو action ساختیم که وظیفه افزایش مقدار و کاهش مقدار counter رو بر عهده دارن.
تو خط 6 مقدار اولیه شمارنده ( counter ) رو مشخص کردیم چون این مقدار رو باید به reducer پاس بدیم.
تو خط 8 از createReducer برای ساخت reducer کمک گرفتیم.
تو تیکه کد بالا ما از addCase برای مشخص کردن عملیات هر Action استفاده کردیم. تو تیکه کد بالا دو addCase داریم ( increment و incrementByAmount )
هر addCase مشخص کننده کارهایی هست که هر action میتونه انجام بده. در حقیقت به ازای هر action باید یک addCase داشته باشیم و داخلش مشخص کنیم هنگامی که action صدا زده شد ( dispatch شد ) چه اتفاقی روی state بیوفته ؟
تو مثال زیر میشه فرق addCase و switch case که در حالت عادی ریداکس ازش استفاده میکردیم رو دید :
addCase در ریداکس تولکیت
.addCase('TOGGLE_TODO', (state, action) => {
const todo = state[action.payload.index]
// "mutate" the object by overwriting a field
todo.completed = !todo.completed
})
switch case در ریداکس خام ( بدون redux toolkit )
case 'TOGGLE_TODO': {
const { index } = action.payload
return state.map((todo, i) => {
if (i !== index) return todo
return {
...todo,
completed: !todo.completed,
}
})
}
همونطور که مشخصه، استفاده از addCase باعث شده کد ما کمتر و تمیزتر باشه.
همچنین در حالت عادی ( بدون ریداکس تولکیت ) ما نمیتونستیم مقادیر رو بصورت مستقیم آپدیت کنیم چون immutable بودن.
اما تو Redux Toolkit به لطف استفاده از immer در پشت صحنه، نگرانی از بابت immutable بودن مقادیر نداریم و میتونیم بصورت مستقیم ویرایششون کنیم. ( خط 4 تیکه کد سمت راست بالا )
حالا که reducer در ریداکس رو متوجه شدیم، بریم ببینیم middleware در ریداکس چیه ؟
middleware در ریداکس !
کتابخانه Redux به ما اجازه میده Action های ارسال شده از کامپوننت رو تا زمانیکه به reducer میرسه رهگیری کنیم.
این رهگیری به کمک middleware در ریداکس امکانپذیره.
تو تیکه کد زیر یک middleware در Redux میتونیم ببینیم :
function simpleMiddleware({ getState, dispatch }) {
return function(next){
return function(action){
// processing
const nextAction = next(action);
// read the next state
const state = getState();
// return the next action or you can dispatch any other action
return nextAction;
}
}
}
شاید به نظر بیاد ساختن middleware در ریداکس کار سختیه، اما middleware های آماده زیادی وجود دارن که ما میتونیم ازشون استفاده کنیم.
مزایای ریداکس در ری اکت چیست ؟
زمانیکه از ریداکس در ریکت استفاده میکنیم، دیگه نیازی نداریم State های خودمون رو از بین کامپوننت های زیادی عبور بدیم ( Props ) تا به مقصد برسونیمش!
ریداکس در ریکت این کار رو به سادگی برای ما انجام میده! فقط کافیه از کامپوننت مقصد، Store خودمون رو بخونیم..
همین موضوع باعث میشه که علت تغییرات اپیکیشن خودمون رو به دلیل واضح بودن Action ها متوجه بشیم چون هر action گویای وظیفشه ( مثل INCREMENT که به معنی افزایش هست )
این یعنی اپیکیشن ما predictable ( قابل پیش بینی ) میشه.
همچنین ما نیازی به نگهداری state در خود کامپوننت ( با useState ) نداریم. همه چیز رو خود Redux در ری اکت مدیریت میکنه.
همین موضوع باعث میشه که توسعه پذیری اپیکیشن ما راحت تر، سریعتر و اصولی تر پیش بره.
اما بریم مزایای ریداکس رو بصورت جزئی تر بررسی کنیم . . .
ریداکس برای ما State های قابل پیش بینی میسازه :
تو کتابخانه redux، همیشه State های قابل پیش بینی داریم. اگه همیشه یک State و Action یکسان به reducer بدیم ( dispatch کنیم ) همیشه نتیجه یکسان میگیریم. چون اصولا تابع reducer یک pure function هست.
حتی امکان مشاهده و دسترسی به State های قبلی و مجددا بعدی رو داریم.
ریداکس اپیکیشن مارو قابل نگهداری میکنه :
کتابخانه Redux یک ساختار و چارچوب مشخص داره و خیلی سختگیرانه عمل میکنه که از ساختار و چارچوب خودش استفاده کنیم.
یعنی اگه ساختار و چارچوب ریداکس رو یاد بگیریم، خیلی راحت میتونیم با اپیکیشن های ریداکسی کار کنیم و از اپیکیشن خودمون نگهداری کنیم.
دیباگ ریداکس آسونه ! :
ریداکس به لطف وجود ساختار مشخص و ارائه ابزار های مختلفی مثل Redux DevTools به ما اجازه میده خیلی راحت تر بتونیم اپیکیشن خودمون رو دیباگ کنیم.
همچنین ما میتونیم تو پروسه های مختلف log بگیریم تا مشکل رو پیدا کنیم. مثلا میتونیم تو action و reducer از موارد مختلف log بگیریم.
زمانیکه ما اپیکیشن بزرگی داشته باشیم، قطعا پروسه دیباگ سخت تری نسبت به اپیکیشن های کوچکتر داریم. اما کتابخانه ریداکس با امکانات خوبی که در اختیار ما گذاشته به ما اجازه میده خیلی راحت بتونیم مشکل رو پیدا کنیم.
ریداکس باعث بهبود عملکرد ( Performance ) اپیکیشن میشه :
کتابخانه redux، در پشت صحنه بهینه سازی هایی انجام میده تا Performance اپیکیشن ما با توجه به کارایی که داریم ازش میگیریم، کاهش پیدا نکنه.
تست ریداکس آسونه :
توابع ریداکس pure function هستن! این یعنی side effect داخلشون نداریم .
همین موضوع باعث میشه فرایند تست اپیکیشن های مبتنی بر Redux، آسون تر باشه.
ریداکس میتونه State های مارو دائمی ذخیره کنه! :
ما میتونیم Store خودمون رو تو localStorage ذخیره کنیم و بعد از Refresh شدن صفحه، مجدد اون Store رو از localStorage فراخوانی کنیم. اینجوری دیگه هیچوقت Store ما پاک نمیشه.
ریداکس از رندر سمت سرور ( Server-Side-Rendering ) پشتیبانی میکنه :
خوشبختانه ریداکس از SSR ( رندر سمت سرور ) پشتیبانی میکنه.
همیشه از ریداکس در ری اکت استفاده کنیم ؟
درسته که Redux در ریکت یک State Management فوق العادس اما دلیل نمیشه که همیشه و در هر اپیکیشنی ازش استفاده کنیم!
تو اپیکیشن های کوچک ما نیازی به Redux در ریکت نداریم.
با اینکه استفاده از Redux Toolkit در ریداکس، پیچیدگی ریداکس رو کم کردیم اما با این حال کمی پیچیدگی به اپیکیشن ما اضافه میکنه. پس در جریان باشید که چه چیزی رو در ازای چه چیزی بدست میاریم..
استفاده از ریداکس در ری اکت، صرفا برای پروژه های بزرگ و سنگین و زمانیکه State های مشترک زیادی دارید که قراره تو کامپوننت های مختلف استفاده بشه، پیشنهاد میشه.
خیلی جاها ابزار های داخلی ری اکت مثل useContext در ریکت میتونه جایگزین خوبی برای ریداکس باشه! مخصوصا زمانیکه با useReducer در ریکت ترکیب میشه.
امروز چه چیزایی یاد گرفتیم ؟
ما بررسی کردیم که Redux چیست و اینکه Redux در ریکت چطور کار میکنه !
همچنین بررسی کردیم که مزایای Redux در ری اکت چیه و چرا باید ازش استفاده کنیم ..
Redux با اینکه یک State Management قدرتمند محسوب میشه، ولی نباید تو هر اپیکیشنی ازش استفاده کنیم!
صرفا زمانیکه مدیریت State در اپیکیشن سخت شده و ما نیاز داریم که یکسری State رو بین کامپوننت های مختلف به اشتراک بزاریم باید از ریداکس استفاده کنیم.
پس بیاید یه مرور کنیم که Redux چطور کار میکنه :
جمع بندی
ما بررسی کردیم و دیدیم redux چیست و اینکه ریداکس در ری اکت چیه و چه کاربردی داره.
بررسی کردیم که نباید از Redux بدون ضرورت استفاده کنیم . بطور مثال از ریداکس در ریکت باید در مواقعی کمک بگیریم که یک State مشترک بین چندین کامپوننت داریم و اپیکیشن ما داره بزرگ میشه.
ریداکس یک State Management قدرتمند و محبوب هست که تو کتابخانه ها و فریمورک های جاوا اسکریپتی ازش استفاده میکنیم. البته در جاوا اسکریپت خام هم میتونیم ازش استفاده کنیم.
البته که ریداکس در ریکت هم کاربرد داره.
تو اپیکیشن های بزرگ که مدیریت State کار سخت و پیچیده ای هست، میتونیم از Redux در ری اکت استفاده کنیم.
Redux در ری اکت یکی از محبوب ترین State Management های حال حاضره.
زمانیکه یک State مشترک بین چندین کامپوننت داریم، استفاده از Redux منطقیه.
ریداکس تولکیت شامل مجموعه ای از ابزار ها و توابع هست که کمک میکنه خیلی ساده تر و راحت تر بتونیم با ریداکس کار کنیم! در حقیقت تو Redux Toolkit از اضافه گویی و موارد اضافی که تو ریداکس خام داشتیم، پرهیز میکنیم.
نه واقعا !
قدیما که Redux Toolkit وجود نداشت، ریداکس پیچیدگی زیادی داشت و یادگیریش کمی سخت و پیچیده بود.
اما به لطف ریداکس تولکیت، ما از موارد اضافه صرف نظر میکنیم و خیلی راحت تر میتونیم از Redux استفاده کنیم.
کتابخانه React Redux منتشر شد تا بتونیم از Redux در ری اکت هم استفاده کنیم.
کتابخانه React Redux توسط تیم Redux ساخته شده و نگهداری میشه.
درباره احمد احمدنژاد
من یه برنامه نویس و توسعه دهنده وب هستم که عاشق دنیای صفر و یکم❤️
نوشتههای بیشتر از احمد احمدنژاد7 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
چقدر عالی Redux در ری اکت رو توضیح داده بودین تشکر
سلام ممنونم از نظر قشنگت و خوشحالم که برات مفید واقع شده 🙂
سلام ممنون از توضیحات بسیاااار خوب و مفیدتون.
من خیلی از مطالبتون استفاده کردم و یاد گرفتم.
میشه خواهش کنم navbar سایتتون رو توی حالت موبایل جمع و جور تر کنین و ارتفاعش رو کاهش بدین؟ برای کسایی که با گوشی مطالبتون رو میخونن یکم آزاردهنده ست. مرسی.
سلام شیوا جان
واقعا ازت ممنونم که چنین قیدبک خوبی دادی، خودم متوجه چنین مشکل بزرگی نشده بودم و بهش توجه نکرده بودم.
تا چند لحظه دیگه مشکل سایدبار رو حل میکنم.
بازم بابت فیدبک ارزشمندت ممنونم و خوشحالم که مطالب سایت برات مفید بوده 🙂
سلام احمد عزیز
ایدوارم حالت خوب باشه
من تازه شروع کردم به یاد گرفتن و میتونم بگم خیلی از موارد و موضوعات رو با توضیحات خوب و روون شما تونستم یاد بگیرم.
ممنون از این که وقت میزاری و به این خوبی توضیح میدی.
موفق باشی
سلام محمدرضا جان
خیلی خوشحالم که مقالات برات مفید واقع شدن، امیدوارم تو این مسیری که تازه شروع کردی حساااالی بترکوونی 💪🔥👊
سلام خیلی ممنون که مفاهیم رو خیلی کامل و به زبان ساده تفهیم میکنید