آموزش ریداکس

آموزش جامع ریداکس (Redux) در ری اکت (React) – قسمت اول

زبان برنامه نویسی جاوا اسکریپت یکی از کاربردی ترین و محبوب ترین زبان های برنامه نویسی در دنیا است که فریمورک ها و کتابخانه های بسیار زیادی دارد. یکی از ابزارهای کاربردی جاوا اسکریپت Redux است. شاید بارها کلمه Redux را شنیده باشید و بپرسید Redux چیست؟ در این مقاله به طور کامل با ریداکس در ری اکت آشنا خواهیم شد.

ریداکس چیست؟

Redux یک کتابخانه کاریردی برای مدیریت وضعیت ها یا state های قابل پیش ‌بینی است که به شما در نوشتن برنامه ‌های جاوا اسکریپت به طور مداوم در بین کاربر، سرور و محیط ‌های بومی رفتار می‌ کنند، کمک می کند و آزمایش آن نیز آسان است. این کتابخانه ساده و متن باز است و API قدرتمندی دارد. در حالی که ریداکس بیشتر به عنوان یک ابزار مدیریت حالت با React استفاده می شود، می توانید آن را با هر چارچوب یا کتابخانه جاوا اسکریپت دیگری استفاده کنید. وزن آن 2 کیلوبایت است، بنابراین لازم نیست نگران فضایی که اشغال می کند باشید. با Redux، وضعیت برنامه شما در یک کتابخانه نگهداری می شود و هر کامپوننت می تواند به هر حالتی که نیاز دارد از این کتابخانه دسترسی داشته باشد.

چی زمانی باید از Redux استفاده کرد

اخیراً یکی از بزرگ‌ترین بحث‌ ها در دنیای frontend درباره Redux بوده است. مدت زیادی پس از انتشار، Redux تبدیل به یکی از داغ ترین موضوعات بحث شد. بسیاری از آن حمایت کردند در حالی که دیگران به مسائلی اشاره کردند.

Redux به شما امکان می دهد وضعیت برنامه خود را در یک مکان واحد مدیریت کنید و تغییرات در برنامه خود را قابل پیش بینی تر و قابل ردیابی تر نگه دارید. همچنین استدلال در مورد تغییراتی که در برنامه شما رخ می دهد را آسان تر می کند. اما همه این مزایا با معاوضه ها و محدودیت هایی هم همراه است. ممکن است افرادی احساس کنند که boilerplate code اضافه می کند و چیزهای ساده را کمی سخت تر می کند. اما این بستگی به معماری کد دارد.

یک پاسخ ساده به این سوال این است که خودتان متوجه خواهید شد که چه زمانی به Redux نیاز دارید. اگر هنوز در مورد اینکه آیا به آن نیاز دارید سردرگم هستید، پس احتمالا نیازی به آن ندارید. نیاز شما به ریداکس معمولاً زمانی مشخص می شود که برنامه شما به مقیاس بزرگی برسد که مدیریت وضعیت یا state آن برای شما بسیار دشوار می شود و به دنبال راه حلی برای ساده تر کردن آن می گردید.

مدیریت وضعیت در Redux چیست؟

مدیریت state اساساً راهی برای تسهیل ارتباطات و به اشتراک گذاری داده ها در بین اجزا است. این یک ساختار داده ملموس برای نشان دادن وضعیت برنامه شما ایجاد می کند که می توانید از آن بخوانید و بنویسید.

اکثر کتابخانه ها مانند React، Angular و غیره با روشی ساخته شده اند تا کامپوننت ها به صورت داخلی وضعیت خود را بدون نیاز به کتابخانه یا ابزار خارجی مدیریت کنند. برای برنامه‌ هایی با مؤلفه‌ های کم به خوبی عمل می‌ کند، اما با بزرگ‌ تر شدن برنامه، مدیریت وضعیت ‌های به اشتراک گذاشته شده در بین مؤلفه ‌ها به یک کار طاقت فرسا تبدیل می‌ شود.

در برنامه ‌ای که داده‌ ها بین اجزا به اشتراک گذاشته می‌ شود، ممکن است دانستن اینکه یک وضعیت باید در کجا قرار بگیرد، گیج‌کننده باشد. در حالت ایده ‌آل، داده‌ های یک مؤلفه باید فقط در یک مؤلفه قرار گیرند، بنابراین اشتراک‌ گذاری داده ‌ها بین کامپوننت های خواهر و برادر دشوار می ‌شود.

به عنوان مثال، در React، برای به اشتراک گذاشتن داده ها بین کامپوننت های siblings، یک حالت باید در کامپوننت parent  قرار بگیرد. روشی برای به ‌روزرسانی این حالت توسط کامپوننت parent ارائه شده است و به عنوان پایه به این کامپوننت های siblings منتقل می ‌شود.

ری اکت و ریداکس

حال تصور کنید چه اتفاقی می ‌افتد وقتی یک حالت باید بین اجزایی که از هم دور هستند به اشتراک گذاشته شود. حالت باید از یک جزء به جزء دیگر منتقل شود تا زمانی که به جایی که لازم است یعنی کامپوننت مقصد برسد.

قبل از شروع اطمینان حاصل کنید که که یک محیط توسعه برای ساخت اپلکیشن React تان اماده کرده اید.
برای این کار شما میتوانید از create-react-app به صورت زیر استفاده کنید:

ریداکت ۲

اساساً، یک state باید به نزدیکترین مؤلفه parent و به مؤلفه بعدی انتقال یابد تا زمانی که به ancestor برسد که برای هر دو مؤلفه که به آن حالت نیاز دارند مشترک است و سپس منتقل می شود. این امر حفظ وضعیت را دشوار و کمتر قابل پیش بینی می کند. همچنین به معنای ارسال داده به اجزایی است که به آن نیاز ندارند.

واضح است که با پیچیده شدن برنامه، مدیریت وضعیت به هم می‌ ریزد. به همین دلیل است که شما به یک ابزار مدیریت حالت مانند Redux نیاز دارید که حفظ این حالت ها را آسان تر می کند. بیایید قبل از در نظر گرفتن مزایای آن، یک مرور کلی از مفاهیم Redux داشته باشیم.

ریداکت ۳

Redux چگونه کار می کند

روش کار Redux ساده است. یک store مرکزی وجود دارد که کل وضعیت برنامه را نگه می دارد. هر کامپوننت می تواند به حالت ذخیره شده دسترسی داشته باشد بدون اینکه نیازی به ارسال props از یک جزء به جزء دیگر باشد.

سه بخش از این سازه وجود دارد: action، store و reducer.

بیایید به طور خلاصه در مورد آنچه هر یک از آن ها انجام می دهند صحبت کنیم. این موضوع بسیار مهم است زیرا به شما کمک می کنند مزایای Redux و نحوه استفاده از آن را درک کنید.

پیشنهاد می کنیم مقاله بازارکار زبان برنامه نویسی پایتون را حتما مطالعه کنید تا از بازارکار پایتون مطلع شوید.

Action در Redux

به زبان ساده، اعمال یک رویداد هستند. آنها تنها راهی هستند که می توانید داده ها را از برنامه به store یا فروشگاه Redux خود ارسال کنید. داده ها می توانند از تعاملات کاربر، تماس های API یا حتی فرم های ارسالی باشند.

actions با استفاده از متد store.dispatch() ارسال می شوند. اکشن ها اشیای جاوا اسکریپت ساده هستند و باید دارای یک خاصیت type باشند تا نوع عملی را که باید انجام شود نشان دهد. آن ها همچنین باید یک payload داشته باشند که حاوی اطلاعاتی باشد که باید توسط اکشن روی آن ها کار شود. اکشن ها از طریق یک Action Creator ایجاد می شوند.

در اینجا نمونه ای از عملکردی است که می توان در حین ورود به یک برنامه انجام داد:

{ 
  type: "LOGIN",
  payload: {
    username: "foo",
    password: "bar"
  }
}
نمونه اکشن:
const setLoginStatus = (name, password) => {
  return {
    type: "LOGIN",
    payload: {
      username: "foo",
      password: "bar"
    }
  }
}

Rdeucer در Redux

reducer ها توابع خالصی هستند که وضعیت فعلی یک برنامه را می گیرند، یک عمل را انجام می دهند و یک حالت جدید را برمی گردانند. این حالت ها به عنوان اشیا ذخیره می شوند و مشخص می کنند که چگونه وضعیت یک برنامه در پاسخ به اقدامی که به store ارسال می شود تغییر می کند.

این بر اساس تابع reduce در جاوا اسکریپت است، که در آن یک مقدار منفرد از چندین مقدار پس از انجام یک تابع فراخوانی محاسبه می شود.

در اینجا مثالی از نحوه عملکرد کاهش دهنده ها در Redux آورده شده است:

const LoginComponent = (state = initialState, action) => {
    switch (action.type) {

      // This reducer handles any action with type "LOGIN"
      case "LOGIN":
          return state.map(user => {
              if (user.username !== action.username) {
                  return user;
              }

              if (user.password == action.password) {
                  return {
                      ...user,
                      login_status: "LOGGED IN"
                  }
              }
          });
default:
          return state;
      } 
};

💡 Reducer ها حالت قبلی برنامه را گرفته و بر اساس اکشنی که به آن ارسال شده است، حالت جدیدی را برمی گرداند.

store در Redux

store وضعیت برنامه را نگه می دارد. به شدت توصیه می شود که فقط یک استور را در هر برنامه Redux نگه دارید. می ‌توانید به وضعیت ذخیره‌ شده دسترسی پیدا کنید، وضعیت را به ‌روزرسانی کنید، و شنوندگان را از طریق روش‌ های کمکی ثبت یا لغو ثبت کنید.

اینطور می توانید یک استور ایجاد کنید:

const store = createStore(LoginComponent);

action انجام شده روی یک state همیشه حالت جدیدی را برمی گرداند. بنابراین، وضعیت بسیار آسان و قابل پیش بینی است.

با Redux، یک حالت کلی در استور وجود دارد و هر جزء به این حالت دسترسی دارند. این امر نیاز به انتقال مداوم حالت از یک مؤلفه به مؤلفه دیگر را حذف می کند. این باعث می شود برنامه شما بهینه تر شود.

npx create-react-app react-redux-tutorial

آموزش جامع Redux: استیت (State) چیست؟

Redux چیست؟ برای پاسخ به این سوال، ابتدا باید درباره مفهوم state در برنامه های جاوااسکریپت (Javascript) صحبت کنیم. عبارت زیر را در نظر بگیرید:
“به عنوان یک کاربر میخواهم بتوانم روی دکمه Click me کلیک کنم و پس از آن یک پنجره Modal به من نمایش داده شود”
شاید درست حدس زدید! حتی در این تعامل ساده نیز یک state وجود دارد. برای مثال، ما میتوانیم state اولیه برنامه را به صورت شی (Object) زیر فرض کنیم:

const state = {
    buttonClicked: 'no',
    modalOpen: 'no'
}

هنگامی که کاربر روی دکمه مورد نظر کلیک میکند، state تغییر می کند و خواهیم داشت:

const state = {
    buttonClicked: 'yes',
    modalOpen: 'yes'
}

شما چگونه تعییرات این state ها را دنبال می کنید؟ اگر state به صورن ناخواسته و تصادفی توسط بخش نامرتبطی از پروژه تعییر کرد چه؟ آیا کتابخانه ای وجود دارد که در این مورد بتواند به ما کمک کند؟

اگر شما قبلا با React کار کرده باشید، با مفهوم state نباید بیگانه باشید. حدس میزنم قبلا کامپویننت های stateful (به معنی دارای state) مانند کد زیر نوشته باشید:

import React, { Component } from "react";
class ExampleComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
        articles: [
            { title: "React Redux Tutorial for Beginners", id: 1 },
            { title: "TypeScript tutorial for beginners", id: 2 }
        ]
        };
    }
    render() {
        const { articles } = this.state;
        return <ul>{articles.map(el => <li key={el.id}>{el.title}</li>)}</ul>;
    }
}

یک کامپوننت (Component) stateful در React، یک کلاس جاوااسکریپت است.

در یک کامپوننت، state نگه دارنده اطلاعاتی است که می تواند برای کاربر رندر (Render) شود. همچنین stateها می توانند در پاسخ به اکشن ها و رویدادها تغییر کنند. درواقع شما می توانید state کامپونننت ها را با استفاده از تابع setState (که در کامپوننت های Class based موجود در React قابل استفاده است) به روز کنید.

بنابراین، در حالت کلی حتی یک برنامه جاوااسکریپتی معمولی نیز شامل انواع state است. به عنوان مثال state عبارتست از:

  • انچه که کاربر می بیند(data)
  • اطلاعاتی که از یک API دریافت می کنیم
  • آدرس URL
  • آیتم هایی که درون یک صفحه انتخاب شده اند
  • خطاهای آتی که قرار است به کاربر نمایش داده شود

تاکنون مفاهیمی مقدماتی را با هم مرور کردیم، حالا بیایید در این باره صحبت کنیم که ریداکس دقیقا چه مشکلی را حل میکند.

پیشنهاد می کنیم مقاله اشتباهات رایج در یادگیری برنامه نویسی را حتما پیش از یادگیری برنامه نویسی مطالعه کنید.

ریداکس چه مشکلی را حل می کند؟

state ها در هرجایی از برنامه های تحت وب دیده می شوند. از این پس هرکجا که درباره state , business logic , component یک برنامه صحبت میکنیم، منظورمان درون یک برنامه نوشته شده توسط React است. البته توجه داشته باشید که این مفاهیم، سوای اینکه از چه کتابخانه خاصی استفاده می کنیم قابل تعممیم به هر نوع معماری فرانت اند دیگری نیز می باشد. اجازه دهید این گونه بپرسم: آیا می توانید تصویر کنید یک برنامه تحت وب مشخص چه تعداد state دارد؟

حتی یک برنامه ساده تک صفحه ای (SPA) در صورتی که اصول و مرزبندی های شفافی را میان لایه های مختلف خود نداشته باشد، با توسعه های آتی پتانسیل لازم برای تبدیل به یک فاجعه خارج از کنترل را دارد! این موضوع (بخصوص) در مورد برنامه های React ایی نیز صادق است.

بله! شما می توانید تا مادامی که برنامه کوچک است state را در یک کامپوننت والد (Parent Component) و یا در context نگه دارید. اما پس از ان تغییر خیلی چیزها، مخصوصا اگر بخواهید عملکردهای بیشتری به برنامه اضافه کنید، به قول رفقای برنامه نویس فرنگی مان Tricky خواهد شد. . برخی مواقع شاید بخواهید به دنبال یک روش یک دست و منسجم برای نگه داری تغییرات state باشید.

کامپوننت های برنامه شما هیچ وقت نباید چیزی درباره منطق برنامه (business logic) بدانند.

متاسفانه این روزها در کامپوننت ها مقدار زیادی logic دیده می شود. آیا راهکار جایگزینی برای رهایی از این عذاب(!) وجود دارد؟

ریداکس می تواند دقیقا مشکلاتی را که اشاره کردیم حل کند. ریداکس کمک می کند که هر کامپوننتی بتواند صرفا به همان بخشی از state که نیاز دارد دسترسی داشته باشد.

جالب تر اینکه، ریداکس به موازات اینکه دیتای مورد نیاز را از یک API دریافت می کند، می تواند حتی منطق برنامه را نیز درون لایه خود (middleware) نگه داری کند.

در بخش بعدی خواهیم دید که چه زمانی و چگونه از ریداکس استفاده کنیم. اما بگذارید پیش از آن یک سوال اساسی مطرح کنیم: آیا باید از ریداکس استفاده کنم؟

آموزش جامع Redux : آیا باید از Redux استفاده کنم؟

باید اعتراف کنم که در این موضوع من بی طرف نیستم، از ان جایی که شیفته ریداکس هستم به هر پروژه ای که می پیوندم استفاده از ریداکس را پیشنهاد می دهم. اما ممکن است شما به ریداکس یا کتابخانه های جایگزین آن مانند Mobx نیاز نداشته باشید. مخصوصا اگر روی پروژه ساده ای کار می کنید.

در React روش های زیادی برای اجتناب از استفاده از ریداکس وجود دارد: children props ، context API

اما برای پروژه های متوسط یا بزرگ من همیشه استفاده از ریداکس (یا یکی از رقبای آن نظیر mobx) را ضروری می بینم: کتابخانه های مدیریت state به شکل جذابی رفتار و عملکرد برنامه را از UI جدا می کنند به طوری که سبب افزایش قابل توج تست پذیری UI و همچنین افزایش بهره وری توسعه دهنده می شوند. بیایید به این موضوع از دید دیگری نیز نگاه کنیم: شاید شما این استدلال را بیاورید که استفاده از ریداکس چنان بی هزینه هم نیست! مخصوصا که یک لایه انتزاعی (Abstraction Layer) دیگر را به برنامه شما اضافه می کند.

شما چه هزینه ای حاضرید بپردازید؟ کامپوینتت هایی نامرتب و شلوغ یا لایه های متعدد abstraction؟

حرف زدن کافیه 🙂 . در بخش بعدی ما شروع میکنیم به ساخت یک اثبات مفهوم (proof of concept) جهت آشنایی با:

  • اصول پایه ای ریداکس
  • ریداکس در کنار ری اکت

اثبات مفهوم رویکردی است برای اثبات ظرفیت های بالقوه یک طرح و مفید بودن آن برای حل یک مشکل.

آموزش جامع Redux : آشنایی با مفوم store در ریداکس

وقتی که برای اولین بار شروع به مطالعه درباره ریداکس کردم کاملا احساس سردرگمی میکردم. کلی واژه جدید وجود داشت: action, reducer, middleware. اما مهم تر از آن ها اینکه برای من مشخص نبود که چطور قرار است همه این بخش ها به هم ارتباط پیدا کنند؟

چیزی که همه این واژه های عجیب-غریب ریداکس را به هم ربط می دهد sotre است. با من تکرار کنید: store. ماشالله یک بار دیگه: store! 😀

نقش store در ریداکس به نوعی جادوگری است! store همه state های برنامه را درون خود نگه میدارد.

بیایید یک store بسازیم تا بتوانیم کار با ریداکس را شروع کنیم. وارد محیط توسعه React خود شوید و ریداکس را نصب کنید:

cd react-redux-tutorial
npm i redux --save-dev

یک فولدر برای store بسازید:

mkdir -p src/js/store

سپس یک فایل جدید به نشانی src/js/store/index.js بسازید و store را مقداردهی اولیه کنید:

// src/js/store/index.js
import { createStore } from "redux";
import rootReducer from "../reducers/index";
const store = createStore(rootReducer);
export default store;

هانطور که میبنید، store نتیجه فراخوانی تابع createStore است که یکی از توابع کتابخانه ریداکس است. createStore به عنوان اولین آرگومان خود یک reducer را می گیرد که در مثال بالا ما rootReducer را به آن پاس داده ایم. (البته خود rootReducer را هنوز نساخته ایم)

شما همچنین میتوانید یک state اولیه را به تابع createStore پاس دهید که برای اجرا در سمت سرور (Server Side Rendering) و پیش بارگذاری state (state preloading) می تواند مفید باشد، اما ما فعلا علاقه ای به انجام این کار نداریم. مهمترین مفهومی که در اینجا باید یاد بگیرید این است که state در ریداکس از reducer ها به دست می اید. یکبار دیگر باهم تکرار کنیم: reducer ها state برنامه را تولید می کنند.

حال که با این مفهوم آشنا شدیم بیایید اولین reducer را در ریداکس بنویسیم. حتما به صفحه ی مسیرهای کارآموزی برنامه نویسی هم سر بزنید.

پاسخ‌ها

آدرس ایمیل شما منتشر نخواهد شد.

پل ورود به بازار تکنولوژی

مشاوره رایگان انتخاب مسیر

با کمک مشاورهای رستاوا آکادمی مسیر کارآموزی مناسب برای خودت رو برای ورود به بازار کار تکنولوژی انتخاب کن

توسعه فردی برای حرفه‌ای شدن

منتورهای رستاوا و دوره‌های ما شما رو برای کارآموزی و در نهایت جذب و استخدام آماده میکنن

مدرک بین المللی و استانداردهای جهانی

یادگیری با استاندار های بین المللی و دریافت مدرک از Credx Academy کانادا

اگر در مسیرهای کارآموزی ما پذیرش بگیری موقعیت‌های کارآموزی و استخدام در پروژه‌ها و شرکت های بین المللی از طریق مجموعه رستاوا به روت باز می شه.

۲ هفته رایگان

همین حالا با منتورها

ارتباط آنی بگیر!