TimTim

سایت خبر خوان

آموزش ریداکس Redux، به زبون آدمی زاد

شنبه 17 فروردین 98 | 11:37 - virgool.io - 18
تا حالا در مورد state management چیزی شنیدید؟ ریداکس یکی از الگوهای جا...

در این نوشته قراره به زبون خودمونی ریداکس و مفاهیمی که پشتشه، رو به زبونی ساده و گام به گام براتون توضیح بدم.

پیشنیازش آشنایی با جاوااسکریپت، ES6 است، همچنین خوبه که تجربه ساخت اپ رو با جاوااسکریپت یا یکی از فریم‌ورک ها و کتابخونه هاش داشته باشید.

خب با گفتن یک سری مفاهیم اولیه شروع کنیم 🚀

📑 تعریف استیت. تمامی اطلاعات که داخل برنامه مون هس، برای مثال

  • اطلاعات برگردونده شده از سرور
  • اطلاعات کاربر (نام، ایمیل، نقش ها، سطوح دسترسی)
  • ورودی های کاربر (user inputs)
  • استیت رابط کاربری (دراپ داون، باز و بسته شدن منو)
  • روتر Router یا location state (همون URL)

✨تابع pure . تابعی که با هر بار فراخوانی آن با پارامتر های یکسان، خروجی یکسانی رو بهمون میده و مقدار ها رو (روی مقدار قبلی) باز نویسی نمی کنه، تابع pure یا گفته میشه. به عبارتی دیگر یک الگوی به‌روزرسانی immutable گفته میشه.

 // pure functions
 function square(x) {
    return x * x
 }
 function squareAll(items) {
   return items.map(square); // return new array
 }

در مقابل تابعی که چنین ویژگی هایی نداشته باشه، impure گفته میشه. برای مثال کارهایی رو مثل ارتباط با api سرور، انجام محاسبات و باز نویسی آن روی داده های قبلی.

// Impure function
 function square(x) {
 updateInDateBase(x); // or http request
    return x * x
 }
 
 function squareAll(items) {
   for (let i = 0; i < items.length; i++) {
    items[i] = square(x); 
   }
 }

📜قوانین سه گانه Redux

  • تمامی استیت برنامه در یک آبجکت جاوااسکریپتی نگه داری میشن که بهش میگیم store
  • استیت ها (همون store) فقط قابل خواندن است، و برای تغییرش باید از اکشن action استفاده کنیم.
  • تغییرات توسط که تابع pure داده میشه به اسم reducer. در واقع استیت قبلی و اکشن را می گیره و برنامه را به‌ استیت جدیدی می بره.

اولین تجربه با ریداکس، ساخت یک شمارشگر

خب بیاید ساده ترین مثال ممکن را با هم بنویسیم. یک شمارشگر (counter) کالا برای افزایش و کاهش تعداد کالا در سبد خرید، خب پس با من کد بزنید!

گام 1️⃣. از تابع reducer شروع کنیم.

function reducer(state, action) {   // 1
 return state; // 2
}
  • 1. همان طور که گفتیم دو پارمتر می گیرد، یکی استیت جاری و یکی هم اکشن.
  • 2. استیت جاری رو هم بدون تغییر بر می گردونه.

گام 2️⃣. حالا اکشن هایی رو که داریم داخل تابع reducer می نویسم.

اکشن action یک آبجکت جاوااسکریپتی است که دو پراپرتی داره.

اولی type که نوع اکشن (مثلا در اینجا افزایش، کاهش)، "type: "INCREMENT

و دومی هم payload که مقادیر استیت جدید مون رو مشخص می کنند. مثلا در اینجا اگه یک لیست از کالا در سبد خرید داشتیم باید می گفتیم که تعداد کالای کدام کالا رو می خواهیم تغییر بدیم.

payload: { productId: 2}

برای سادگی فعلا payload را در نظر نمی گیریم. بیاید اکشن هامون رو پیاده سازی کنیم.

function reducer(state = 0, action) {  // 1
 if (action.type === "INCREMENT") {  // 2
 return state + 1;
 } else if (action.type === "DECREMENT") {  // 3
 return state - 1;
 } else {
 return state; // 4 
 }
}
  • 1. چون شمارشگر از 0 شروع می شود، پس state اولیه مون میشه 0.
  • 2. اگه کاربر دکمه + رو بزنه، نوع اکشن افزایش است که اسمشو میزاریم "INCREMENT" اتفاق می افته.
  • 3. اگه کاربر دکمه - رو بزنه، نوع اکشن کاهش است که اسمشو میزاریم "DECREMENT" اتفاق می افته.
  • 4. اگه غیر از موارد بالا اکشنی از نوع دیگه داشتیم، استیت جاری رو برگردون.

🎉 خب تبریک میگم! اولین تابع reducer خودتون رو نوشتید! به همین سادگی. بیاید یه دستی بهش بکشیم خب میشه به جای if else ها از switch/case استفاده کنیم.

خروجی تابع reducer برای شمارشگر
خروجی تابع reducer برای شمارشگر

گام 3️⃣. افزودن کتابخونه Redux، و ساخت Store

برای اینکه سه قانونی که گفتیم رو به شکل آماده داشته باشیم، از کتابخونه Redux استفاده می کنیم. تگ script زیر رو به head فایل html مون اضافه می کنیم. ریداکس سه تابع مهم داره، که بهشون می پردازیم.

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.1/redux.min.js">

حالا بعد از تابع reducer کد زیر رو اضافه می کنیم. که بتونیم یک store بسازیم با استفاده از createStore.

// var createStore = Redux.createStore // in es5
// or es6:
const { createStore } = Redux;

و به این شکل store خودمون رو با پاس دادن به createStore می سازیم.

const store = createStore(reducer);
console.log(store.getState()); // 1
  1. استیت جاری رو با getState می گیریم. چون مقدار اولیه استیت مون رو برابر 0 دادیم پس خروجی برابر 0 میشه.

گام 4️⃣. dispatch کردن یک اکشن

قانون دوم ریداکس رو باهم مرور می کنیم:

  • استیت ها (همون store) فقط قابل خواندن است، و برای تغییرش باید از اکشن action استفاده کنیم.

معنی استفاده از action، است که یک اکشن را dispatch (اِعزام) کنیم.

store.dispatch({ type: "INCREMENT" }); // 1
console.log(store.getState()); // 2
  1. فراخوانی تابع dispatch، با اکشنی از نوع "INCREMENT"، استیت برنامه رو عوض می کنه.
  2. همان طور که انتظار داریم خروجی 1 رو بهمون میده چون استیت قبلی‌مون 0 (استیت اولیه) بوده.

گام 5️⃣ (آخر). گوش دادن به تغییرات store با subscribe

تقریبا کار تمومه! باید به محض اینکه تغییراتی که روی استور میدیم، در هر جایی ازش با خبر بشیم. یعنی نیازی نباشه که هر چند ثانیه یک بار تابع getState رو فراخوانی کنیم.

store.subscribe( () => console.log(store.getState() )); // 1
  1. تابع subscribe در callback را هنگام dispatch شدن اکشن جدید اجرا می کند. در اینجا ما استیت جاری رو می گیریم.

خب بیاید در عمل ببینیم چطوری کار می کنه.

اگه بیایم در رویداد کلیک document، اکشن INCREMENT رو dispatch کنیم. داریم.

document.addEventListener('click', () => {
    store.dispatch({type: "INCREMENT"})
})

یعنی با هر بار کلیک، شمارشگر یک واحد افزایش پیدا می کند. [خودتان ببینید]

خروجی مرحله پایانی
خروجی مرحله پایانی


مثال کامل شده شمارشگر با جاواسکریپت



ریداکس در یک نگاه

ریداکس در یک نگاه
ریداکس در یک نگاه


  1. کاربر با کلیک (هر رویداد event دیگر) یک اکشن را dispatch می‌کند. (سوال: تو نظرات بگید که اکشن مون در شکل بالا typeو payloadش چیه؟)
  2. تابع reducer استیت قبلی و اکشن رو میگیره، و یه استیت جدید بر می‌گردونه.
  3. با subscribe روی store، استیت جدید رو میگیریم و رابط کاربری رو باهاش به‌روز می‌کنیم.




🙏 در پایان خوشحال میشم، نظراتتونو برای بهتر شدن این پست بهم بگید.

منبع: [ + ,+]

ویرگول,برنامه نویسی,وب,ریداکس,redux,آموزش ریداکس,