یادگیری redux، ساده تر از چیزی که فکرش رو میکنی!

https://vrgl.ir/rBeFh ما برای استفاده از دیتا توی کامپوننت ها از props استفاده میکنیم تا بتونیم دیتا رو به کامپوننت ها پاس بدیماما وقتی تعداد کامپوننت های تو در تو زیاد بشه استفاده از این روش اصلا پیشنهاد نمیشه و به این شلوغ کاری به اصطلاح prop drilling گفته میشه مثل عکس پایین:توی عکس بالا ما برای اینکه دیتارو توی فایل textContent استفاده کنیم باید اون دیتارو از تمام پرنت هاش عبور بدیم تا به این برسهراه حلی که برای این مشکل هست global state management هست که به روش های گوناگون و با ابزار های مختلف میشه پیادش کرد از جمله context api و redux که ما توی این مقاله قراره راجب redux صحبت کنیم ریداکس یه کتابخونه برای مدیریت کردن استیت های گلوبال هستش که توی کتابخونه و فریمورک هایی مثل ری اکت و انگولار ازش استفاده میشه البته اگه پروژه بزرگ و پیچیده باشه مناسبتره در غیر اینصورت چیزایی مثل context api کفایت میکنهتوی این مقاله قراره هم مفهومات ریداکس رو یاد بگیریم و هم ساختار و نحوه نوشتنش رو (کسایی هستن که مفهومات رو بلدن ولی نمیدونن چطور ریداکس رو پیاده کنن) پس من روند پیاده سازیشو قدم به قدم پیش میبرم و در حین پیش بردن توضیحات لازم رو هم میدم1. نصب موارد لازمnpm install redux react-redux redux-thunkاز redux برای نوشتن store استفاده میکنیم و از react-redux برای ارتباط گرفتن ری اکت و ریداکس استفاده میشه برای مثال تغییر دادن دیتای توی store و یا خوندن دیتای مربوطه از استیت گلوبال و از redux-thunk هم برای اضافه کردن قابلیت async به اکشن هایی که باید به صورت async باشن استفاده میشه چون در صورت عادی redux به اکشن ها اجازه نمیده به صورت asynchronous نوشته بشن2.ساخت پوشه redux در پروژه پوشه redux شامل دو پوشه actions , reducers هست:پوشه actions شامل یه فایل index هستش که قراره فانکشنهایی رو برای دستور های مختلف توش بنویسیم برای مثال :اکشن asyncهمونطور که توی عکس بالا میبینید اکشن در واقع یه فانشکن هستش که برای عملکرد خاصی نوشته میشه و در نتیجه دیتایی رو با یه اسم(type) به خصوصی مخابره(dispatch) میکنه به ردیوسر توی عکس بالا فانکشن همونطور که از اسمش پیداس برای گرفتن اطلاعات محصول نوشته شده ولی اگه دقت کنیم داره یه فانکشن async بر میگردونه که مابقی کار رو اون انجام میده ! قضیه چیه؟ما برای استفاده async از اکشن ها نیاز به redux thunk که مارو قادر به نوشتن اکشن async میکنه و نحوه نوشتن اکشن async به شکل بالاس اما یه اکشن ساده به شکل زیره:اکشن sync2. پوشه reducers شامل فایل های ردیوسر مختلف برای اکشن های مختلف با اسم های xxxReducer.js (بجای xxxهرچی میتونید بزارید) هستش و یه فایل index به شکل زیر:ما میتونیم از تک تک فایل های ردیوسر به صورت مستقیم استفاده کنیم و نیازی به ایندکس نداشته باشیم اما برای مرتب تر شدن ما فایل index رو به شکل زیر استفاده میکنیم:ما با استفاده از combineReducer تمام دیتاهایی که ردیوسر ها برمیگردونن رو توی یه آبجکت جمع میکنیم تا استفاده ازشون خیلی ساده تر باشهتوی عکس بالا ما دیتایی که از ردیوسر productsReducer برگشته رو ریختیم توی پراپرتی products هرجا بخوایم با این اسم میتونیم از دیتا استفاده کنیمهر فایل ردیوسر هم به شکل زیر هست :فایل xxxReducer ما شامل یه فانشکن هستش که دوتا پارامتر میگیره اولی state هستش که باید یه مقدار اولیه هم بهش بدید در عکس بالا یه آبجکت خالی هستش و پارامتر دوم action هستش که اگه توی عکسای بالاتر توجه کرده باشید این action در اصل یه آبجکته که از فانکشن اکشن مخابره شده :{type: 'GET_PRODUCTS_DETAILS' , payload: Product}داخل فانکشن ما از switchاستفاده میکنیم که اسم اکشن مخابره شده رو ( همون type) رو چک بکنیم و در ازای هر اسمی دیتای به خصوص خودشو ( همون payload) رو برگردونیم و در صورت نبودن هیچ کدوم از اسما همون استیت پیشفرض رو برمیگردونیم و این دیتا توی پراپرتی مخصوص خودش توی آبجکت RootReducerذخیره میکنیم:حالا این دیتا هر جایی با اسم ProductDetailsدر دسترس هستش3. ایجاد store و provider در فایل root پروژهما برای دسترسی به دیتایی که توسط اکشن ها و ردیوسر ها دست به دست میشن و توی rootReducer قرار میگیرن نیاز داریم تا توی فایل روت کارایی رو انجام میدیمخب ما مثل عکس بالا توی فایل index باید store رو به وسیله createStore بسازیم که پارامتر اولش rootReducer هست که با combineReducer ساخته شده تا به همه دیتاهایی که ردیوسر ها برمیگردونن یه جا توی یه ابجکت دسترسی داشته باشیم و پارامتر دوم applyMiddleWare هستش که میاد thunk رو به عنوان یه واسط به ریداکس اضافه میکنه تا بتونیم اکشن های async هم انجام بدیم و در آخر با provider دور کامپوننت App که هفت جد و آباد همه ی کامپوننتای دیگس محاصره میکنیم و بهش پراپی میدیم که استور رو دربر داره و حالا هر کامپوننتی داخل app.js هر چقدر هم تو در تو باشه میتونه به صورت مستقیم به هر دیتایی دسترسی داشته باشه بدون اینکه از بالا تا پایین یکی یکی فلان دیتا رو بهش پاس بدیم که در ادامه میگم چطور.4. استفاده از اکشن ها و استفاده از ردیوسر هاخب لپ کلام بخوام بگم اینطوریه که ما یا میخوایم یه اکشن رو بفرستیم تا دیتا رو تغییر بده و یا میخوایم دیتایی که تغییر کرده رو از ردیوسر بگیریم و توی یو ای نمایش بدیمارسال یا مخابره یک دستور(اکشن):همونطور که تو عکس بالا میبینید ما برای استفاده از هر اکشنی اول اون اکشن رو از redux/actions ایمپورت میکنیم و بعد با استفاده از useDispatch اکشنمون رو مخابره میکنیم.2. گرفتن دیتا از ردیوسر:خب اگه یادتون باشه بالا تر توی rootReducer ما دیتایی که از یکی از ردیوسر ها برگشته بود رو روی پراپرتی productDetails ریختیم و توی عکس بالا میبینیم که میتونیم با استفاده از useSelector یه کال بک انجام بدیم که یه پارامتر میگیره که همون rootReducer هستش (تو عکس بالا با اسم state) و از این استیت دقیقا دیتایی که میخوایم رو میگیریم و میریزیم توی متغیر و تو ui نمایشش میدیم به همین سادگی!توی گیف پایین تموم روند که بالاتر گفتم رو یجا میبینید:فرستادن اکشن از ui به reducer و اپدیت کردن state توسط ردیوسر در داخل استیت و در نهایت آپدیت شدن uiخب اگه تا اینجا خوندی و خسته نشدی بیا تا یه اموزش کوچیک هم در ادامه بهت بدم اونم استفاده از redux persist هستش که برای استفاده ازش فقط کافیه یه کوچولو فایل src/index.js رو تغییر بدیم اما اصلا redux persist چی هستش؟مطمعنا خیلیاتون دلتون میخواد دیتایی که هر سری اپدیت میکنید رو نگه دارید و طوری نباشه که با یه رفرش همش بپره!خب این پکیج دقیقا برای همینه که میاد هر دیتارو که از ردیوسر میگیره و توی لوکال استوریج ذخیره میکنه تا با رفرش کردن اون دیتا نپرن!برای استفاده ازش اول اینطوری نصبش کنید:npm install redux-persistبعدش فایل روت رو بجای اون تغییراتی که بالاتر گفتم اینطوری بزارید :چیزایی که لازمه رو طبق عکس بالا از Redux persist ایمپورت میکنیم.آبجکت persistConfig میاد تنظیم میکنه که دقیقا چیو چجوری سیو کنه تو لوکال مثلا ردیوسری داریم که نمیخوایم توی لوکال ذخیره بشه دیتاش و با هر رفرش ناپدید شه از پراپرتی blackList که آرایه هست استفاده میکنیم و اسمی که توی RootReducer به این ردیوسر دادیم رو به صورت استرینج توی این آرایه قرار میدیم.متغیر persistedReducer میاد قبل از استور rootReducer رو میگیره و ذخیره میکنه و حالا به Store به عنوان پارامتر اول بجای rootReducer میایم متغیر persistedReducer رو پاس میدیم که با هر رفرش خالی نکنه دیتا رو ما باید App رو علاوه بر provider با PersistGate هم بپوشونیم که که متغیر persistor هم حکم Store برای PersistGate رو داره و loading هم پراپی هستش که میدیم تا لود شدن دیتا بیاد و اونو نمایش بده مثلا : laoding={<Loading />} .فقط حواستون باشه چه مقدار دیتا و چه دیتایی توی لوکال ذخیره میکنید چون هم فضاش محدوده و هم میتونه دیتایی باشه که نخواید توی لوکال استوریج ذخیره شهخب این مقاله اینجا تموم شد و دیدیم که ریداکس همچین غول زشت و بی شاخ و دمی هم که ازش میترسن نیست و برعکس خیلی هم عالیه :)امیدوارم خسته نشده باشی و بدردت خورده باشهخدانگهدار موفق باشی?