در این نوشته قراره به خیلی خودمونی ریداکس و مفاهیمی که پشتشه، رو به زبونی ساده و گام به گام براتون توضیح بدم.
پیشنیازش آشنایی با جاوااسکریپت، ES6 است، همچنین خوبه که تجربه ساخت اپ رو با جاوااسکریپت یا یکی از فریمورک ها و کتابخونه هاش داشته باشید.
خب با گفتن یک سری مفاهیم اولیه شروع کنیم ?
? تعریف استیت. تمامی اطلاعات که داخل برنامه مون هس، برای مثال
✨تابع 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); } }
خب بیاید ساده ترین مثال ممکن را با هم بنویسیم. یک شمارشگر (counter) کالا برای افزایش و کاهش تعداد کالا در سبد خرید، خب پس با من کد بزنید!
function reducer(state, action) { // 1 return state; // 2 }
اکشن 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 } }
? خب تبریک میگم! اولین تابع reducer خودتون رو نوشتید! به همین سادگی. بیاید یه دستی بهش بکشیم خب میشه به جای if else ها از switch/case استفاده کنیم.
برای اینکه سه قانونی که گفتیم رو به شکل آماده داشته باشیم، از کتابخونه 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
قانون دوم ریداکس رو باهم مرور می کنیم:
معنی استفاده از action، است که یک اکشن را dispatch (اِعزام) کنیم.
store.dispatch({ type: "INCREMENT" }); // 1 console.log(store.getState()); // 2
تقریبا کار تمومه! باید به محض اینکه تغییراتی که روی استور میدیم، در هر جایی ازش با خبر بشیم. یعنی نیازی نباشه که هر چند ثانیه یک بار تابع getState رو فراخوانی کنیم.
store.subscribe( () => console.log(store.getState() )); // 1
خب بیاید در عمل ببینیم چطوری کار می کنه.
اگه بیایم در رویداد کلیک document، اکشن INCREMENT رو dispatch کنیم. داریم.
document.addEventListener('click', () => { store.dispatch({type: "INCREMENT"}) })
یعنی با هر بار کلیک، شمارشگر یک واحد افزایش پیدا می کند. [خودتان ببینید]
مثال کامل شده شمارشگر با جاواسکریپت
? در پایان خوشحال میشم، نظراتتونو برای بهتر شدن این پست بهم بگید.
+ تکمیلی این مقاله: راهنمای کامل مدیریت State در انگولار