مقایسه مدیریت state با استفاده از هوک ()useState و Redux

مدیریت state برای مدیریت داده‌های یک برنامه، نحوه تعامل کاربران با آن و نحوه رفتار بخش‌های مختلف برنامه بسیار مهم است. مدیریت state چیزی نیست که فقط در React از آن استفاده کنیم، بلکه در ابزارهای محبوب دیگر مانند Angular.js، Vue.js و Next.js نیز مورد استفاده قرار می‌گیرد. دو راه متداول برای مدیریت state وجود دارد: ()useState و Redux. اما گزینه‌های دیگری مانند MobX، Zustand و Recoil نیز هستند.

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

مدیریت state چیست و چرا اهمیت دارد؟

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

چه نوع سایت‌ها و برنامه‌هایی از مدیریت state استفاده می‌کنند؟

مدیریت state در بسیاری از وب سایت‌ها و برنامه‌ها، از ساده تا پیچیده، مورد استفاده قرار می‌گیرد. React و فریم‌ورک‌هایی مانند Angular.js، Vue.js و Next.js اغلب از مدیریت state برای مدیریت داده‌ها و کنترل نحوه رفتار کامپوننت‌ها استفاده می‌کنند.

هنگام انتخاب استراتژی مدیریت state چه مواردی را باید در نظر بگیریم؟

  1. پیچیدگی برنامه: برای برنامه‌های ساده با تعداد کامپوننت‌های کم، بهتر است از ()useState استفاده کنیم. برای برنامه‌های پیچیده با تعاملات گسترده، Redux انتخاب بهتری می‌باشد.
  2. اندازه تیم و سطح مهارت: ()useState برای تیم‌های کوچک‌تر یا توسعه‌دهندگانی که کم‌تجربه هستند می‌تواند مفید باشد، زیرا درک آن آسان است. Redux می‌تواند برای تیم‌های بزرگ‌تر با توسعه‌دهندگان باتجربه خوب باشد.
  3. وضعیت اشتراک گذاری: استفاده از مدیریت state متمرکز Redux در برخی موارد راحت‌تر از هوک ()useState است.
  4. مقیاس پذیری: Redux ویژگی‌های پیشرفته‌ای را ارائه می‌دهد که به مدیریت stateهای پیچیده کمک می‌کند.

مثال‌هایی از مدیریت state با Redux و ()useState

برای درک بهتر مدیریت state، می‌خواهیم یک مثال عملی را باهم بررسی کنیم که نشان می‌دهد هوک ()useState و Redux چگونه در React کار می‌کنند.

راه اندازی پروژه

ابتدا به پوشه پروژه می‌رویم. با استفاده از دستور create-react-appیا ابزار Vite یک React boilerplate ایجاد می‌کنیم. ما در این مقاله از vite استفاده می‌کنیم، زیرا برای توسعه سریع‌تر است و پیکربندی آسانی دارد. Vite همچنین کارایی بیشتری دارد و از دیگر فریم ورک‌های فرانت‌اند مانند Svelte پشتیبانی می‌کند.

سپس در ادیتور دستور زیر را وارد می‌کنیم:

npx create-react-app ./ or npx create-vite@latest ./

./ React boilerplate را درست داخل پوشه یا دایرکتوری ایجاد شده برای ما می‌سازد.

مدیریت state با ()useState

()useState یک هوک داخلی در React است و state برنامه‌های React را به صورت local مدیریت می‌کند. هوک ()useState همچنین قابلیت‌های مدیریت state را در فانکشنال کامپوننت‌ها معرفی می‌کند. این بدان معناست که اکنون می‌توانیم از منطق stateful در فانکشنال کامپوننت‌ها استفاده کنیم.

در React، ما به هوک‌های مختلف دیگری دسترسی داریم که می‌توانیم آن‌ها را import کرده و در برنامه‌های خود استفاده کنیم. این هوک‌ها برنامه ما را پویاتر و کارآمدتر می‌کند.

مزایای استفاده از هوک ()useState در برنامه React

  1. ()useState دارای footprint کوچک‌تری نسبت به کتابخانه‌های external مدیریت state مانند Redux است. این موضوع باعث کاهش اندازه بسته نرم افزاری و بهبود عملکرد می‌شود.
  2. ()useState اجازه می‌دهد تا مدیریت state واضح‌تری در فانکشنال کامپوننت‌ها داشته باشیم.

معایب استفاده از هوک ()useState در برنامه React

  1. مدیریت state کامپوننت‌های پیچیده با متغیرهای زیاد، دشوار است.
  2. با توجه به قابلیت‌های محدودتری که دارد، می‌تواند منجر به مسائلی مانند prop drilling شود که در صورت عدم درک درست آن می‌تواند کمی گیج‌کننده باشد.
  3. باعث ایجاد یک رندر مجدد از کامپوننتی می‌شود که بر عملکرد تأثیر می‌گذارد.

نحوه استفاده از هوک ()useState در برنامه‌های React

می‌خواهیم برنامه‌ای بسازیم که رنگ یک متن را بر اساس ورودی کاربر تغییر دهد. به عنوان مثال اگر inputای که کاربر وارد ‌می‌کند red باشد، رنگ متن به قرمز تغییر پیدا کند.

استفاده از ()useState شامل یک فرآیند ساده است:

  • هوک ()useState را از کتابخانه 'react'import می‌کنیم.
  • یک متغیر state و مقدار اولیه آن را با استفاده از array destructuring تعریف می‌کنیم.
  • سپس، متغیر state دیگری را تعریف می‌کنیم که هنگام تایپ، رنگ منتخب کاربر را به خود اختصاص دهد.
  • از متغیر state و تابع setter مربوط به آن در منطق کامپوننت برای خواندن یا به‌روزرسانی state استفاده می‌کنیم.

به عنوان مثال:

import React, { useState } from 'react';

const State = () => {
  const [text, setText] = useState('black');
  const [color, setColor] = useState('black'); // Another state to store the chosen color by the user

  const handleInputChange = (e) => {
    setText(e.target.value);
  };

  // A function is been declared
  const handleButtonClick = () => {
    setColor(text); // it updates the chosen color when the button is clicked
  };

  return (
    <div>
      <p style={{ color: color }}>
        Progressively effective resources via business metrics.
      </p>
      <br />
      <div className='inputBtn-container'>
        <input
          type='text'
          className='input'
          value={text}
          onChange={handleInputChange}
        />
        <button className='btn' onClick={handleButtonClick}>
          Change text color
        </button>
      </div>
    </div>
  );
};

export default State;

در کد بالا، متغیر state با نام textبا استفاده از ()useState روی state اولیه (color) تنظیم شده است. تابع setTextنیز طوری تنظیم شده است که با کلیک روی دکمه، مقدار رنگ را به‌روزرسانی می‌کند.

دومین state تعریف شده، ذخیره به‌روزرسانی رنگی است که توسط کاربر وارد می‌شود. بنابراین رنگ text تا زمانی که بر روی دکمه کلیک نشود بدون تغییر باقی می‌ماند. پس از کلیک روی دکمه، state رنگ با مقدار text به‌روزرسانی می‌شود و رنگ text به آنچه کاربر تایپ می‌کند تغییر می‌نماید.

مدیریت state با Redux

Redux یک کتابخانه جاوااسکریپت برای مدیریت stateها در برنامه‌ها است که با React و سایر فریم‌ورک‌ها کار می‌کند. این کتابخانه به ما کمک می‌کند تا global state برنامه خود را مدیریت کنیم. علاوه بر این، عملکرد برنامه را نیز بهبود می‌بخشد.

همچنین می‌توانیم Redux را به عنوان یک کنترل کننده ترافیک برای داده‌های برنامه در نظر بگیریم. زیرا این اطمینان را ایجاد می‌کند که اطلاعات مناسب به بخش‌های مناسب می‌روند، بنابراین همه چیز به آرامی اجرا می‌شود.

مزایای استفاده از Redux

Redux ممکن است در ابتدا پیچیده به نظر برسد، اما چندین مزیت دارد که یادگیری آن را ارزشمند می‌کند:

  1. می‌توانیم Redux را نه تنها در برنامه‌های React بلکه با سایر فریم‌ورک‌های فرانت‌اند مانند Angular.js، Vue.js و Next.js مورد استفاده قرار دهیم.
  2. Redux این امکان را به ما می‌دهد که به جای پراکندگی stateها در بسیاری از کامپوننت‌ها، همه آن‌ها را در یک store مرکزی ذخیره کنیم. این کار درک، ردیابی و مدیریت state برنامه را آسان‌تر می‌کند.
  3. بسیاری از شرکت‌های بزرگ از Redux برای مدیریت state برنامه خود استفاده می‌کنند.

معایب استفاده از Redux

  1. استفاده از Redux می‌تواند برنامه ما را پیچیده‌تر کند، به خصوص اگر در استفاده از آن کم‌تجربه هستیم. ما باید مفاهیم جدیدی را یاد بگیریم و کد بیشتری بنویسیم، که همین موضوع ممکن است بسیار زمان‌بر باشد.
  2. Redux در مقایسه با ()useState به کد بیشتری نیاز دارد.
  3. اگر برنامه‌ای که داریم کوچک است یا نیازهای پیچیده‌ای ندارد، استفاده از Redux ممکن است غیرضروری باشد.
  4. دیباگ کردن راه اندازی Redux می‌تواند کمی چالش برانگیز باشد.

نحوه استفاده از Redux

ابتدا باید پکیج Redux را نصب کنیم:

npm install redux react-redux @reduxjs/toolkit

ما برای این کار سه دستور را باهم وارد کردیم که می‌توانستیم هر یک را به شکل جداگانه نیز نصب کنیم. در ادامه هر دستور را به صورت جداگانه بررسی می‌کنیم که چه کاری را انجام می‌دهد.

  • دستور npm install reduxکتابخانه Reduxرا نصب می‌کند.
  • دستور react-reduxبه این معنی است که Redux در یک برنامه React استفاده می‌شود. یعنی یکپارچگی را فراهم می‌کند.
  • دستور @reduxjs/toolkitابزارهایی را ارائه می‌دهد که کار با Redux را برای توسعه‌دهندگان تازه‌کار ساده‌تر می‌کند.

در مرحله بعد به فایل package.jsonمی‌رویم تا مطمئن شویم که Redux به dependencyهای ما اضافه شده باشد. این فایل شامل اطلاعات مهمی در مورد پکیج‌های مورد استفاده در پروژه می‌باشد.

سپس {configureStore} را از @reduxjs/toolkitبه فایلmain.jsیا index.js import می‌کنیم.

کامپوننت اصلی برنامه خود را داخل تگ provider قرار می‌دهیم و storeرا به عنوان یک ویژگی (props) به provider می‌دهیم. این کار باعث می‌شود تا store در سراسر برنامه در دسترس باشد.

اصطلاحات کلیدی در Redux

Store: یک container در برنامه مانند یک واحد storage است. ما reducer را در داخل store تعریف می‌کنیم.

Redux بر اساس اصول یک store متمرکز عمل می‌کند. به این ترتیب، کل state برنامه را در خود نگه می‌دارد. زمانی که هر کامپوننت نیاز به دسترسی به state یا نیاز به یک به‌روزرسانی داشته باشد، با store تعامل می‌کند. سپس store داده‌ها را مدیریت کرده و تغییرات را در هر بخش برنامه منتشر می‌نماید.

Reducer: یک reducer آبجکتی است که دو ورودی دارد: state قبلی و یک action. به این ترتیب state به‌ روز شده را بر اساس actionهای ارسال شده return می‌کند. reducer اکشن‌ها را بررسی می‌کند و تصمیم می‌گیرد که چگونه state برنامه را به‌روزرسانی کند.

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

مثال Redux

می‌خواهیم برنامه‌ای بسازیم که رنگ را بر اساس ورودی کاربر تغییر دهد و این بار از Redux برای مدیریت state استفاده کنیم. ابتدا پوشه‌ای به نام componentsمی‌سازیم. داخل آن پوشه، فایلی به نامChangeColor.jsxایجاد می‌کنیم.

در دایرکتوری پروژه خود، یک پوشه با نام featuresایجاد می‌کنیم. داخل این پوشه، فایلی به نام Color.jsایجاد می‌نماییم تا منطق Redux را برای برنامه ما نگه دارد.

در مرحله بعد، می‌خواهیم به کاربران اجازه دهیم تا رنگ مورد نظر خود را وارد کنند. برای انجام این کار، هوک ()useState را به صورت زیر در فایل ChangeColor.jsximport می‌کنیم:

import { useState } from 'react';   // useState() hook

const ChangeColor = () => {
  const [color, setColor] = useState(''); 
  return (
    <div>
      <p>Progressively effective resources via business metrics.</p>
      <br />
      <div className='inputBtn-container'>
        <input
          type='text'
          className='input'
        />
        <button className='btn'>change color text</button>
      </div>
    </div>
  );
};

export default ChangeColor;

فایل color.jsکه منطق Redux را برای برنامه تنظیم می‌کند، شامل کد زیر می‌باشد:

// Import necessary functions from Redux Toolkit
import { createSlice } from "@reduxjs/toolkit";// Creating a slice for functionality is essential.

// Define the initial state for the slice
const initialState = "black"


// Create a slice using the createSlice function
const themeSlice = createSlice({
  name: 'theme', // Name of the slice
  initialState: { value: initialState},// Initial state for the slice
  reducers: {
    changeColor: (state, action)=>{
      state.value=action.payload // Update the color value based on the dispatched action
    },
    }
  }
})

بررسی فایل color.js

  • createSliceتابعی از Redux Toolkit است که به توسعه‌دهندگان اجازه می‌دهد تا reducerها را به روشی واضح و سازمان‌یافته ایجاد کنند. تقسیم منطق و دسترسی به آن در سراسر برنامه را ساده می‌کند. با createSlice، تغییر مقادیر و درک کد آسان‌تر می‌شود.
  • nameرشته‌ای است که نام slice را مشخص می‌کند. این نام به عنوان پیشوند رشته‌های action type تولید شده، مورد استفاده قرار می‌گیرد.
  • initialStateمقدار state اولیه برای slice را مشخص می‌کند.
  • Reducersهمانطور که در بخش قبل به آن اشاره کردیم،آبجکت‌هایی هستند که دو ورودی دارند: state قبلی و یک action. به این ترتیب state به‌روز شده را بر اساس actionهای ارسال شده return می‌کنند. با استفاده از reducerها، می‌توانیم برنامه را به صورت ساختاریافته مدیریت و به‌روزرسانی نماییم.
  • stateبه داده‌های ذخیره شده و مدیریت شده توسط برنامه اشاره دارد. State مقادیر فعلی متغیرها، ویژگی‌ها یا فیلدهایی را که تعیین می‌کنند برنامه چگونه رفتار ‌کند یا ظاهر آن چگونه باشد، نگه‌داری می‌کند.
  • actionیک آبجکت جاوااسکریپتی ساده است که قصد تغییر state را توصیف می‌کند. به عبارت دیگر action نحوه ارتباط ما با reducerها برای شروع به‌روزرسانی‌های state است.

پس از تعریف منطق reducer، می‌توانیم آن را export کنیم و در هر جایی که نیاز به مدیریت state داریم آن را import کرده و مورد استفاده قرار دهیم. مثلا در فایل changeColor.jsx. فایل زیر، فایل export شده برای فایل changeColor.jsx می‌باشد:

import { createSlice } from "@reduxjs/toolkit";

const initialState="black"
export const themeSlice = createSlice({
  name: 'theme',
  initialState: { value: initialState},
  reducers: {
    changeColor: (state, action)=>{
      state.value=action.payload
    }
  }
})
// Export the reducer function
export const { changeColor } = themeSlice.actions
export default themeSlice.reducer

بررسی فایل changeColor.jsx

  • ما هوک useSelectorرا از react-redux import می‌کنیم تا داده‌ها را از Redux store دریافت کنیم. این کار به ما کمک می‌کند تا مقدار رنگ فعلی را از state دریافت نماییم.
  • سپس هوک useDispatchرا از react-reduximport می‌کنیم تا actionها را به Redux store ارسال کنیم. به این ترتیب می‌توانیم مقدار رنگ را در state به‌روزرسانی کنیم.
  • و در نهایت فایل Color.jsرا که حاوی منطق Redux و شامل reducer و action تغییر رنگ است، import می‌کنیم.

به این ترتیب:

  1. رنگ فعلی را با استفاده از هوک useSelectorاز Redux store دریافت می‌کنیم.
  2. یک المنت input را رندر می‌کنیم که در آن کاربران می‌توانند رنگ مورد نظر خود را تایپ کنند.
  3. یک event handler برای مدیریت تغییرات در مقدار input تعریف می‌کنیم. هنگامی که کاربر یک رنگ را در input تایپ می‌کند، این event handler فراخوانی می‌شود.
  4. هنگامی که کاربر روی دکمه «تغییر رنگ» کلیک می‌کند، event handler یک action با مقدار رنگ به روز شده را به Redux store ارسال می‌نماید.

با این تغییرات، کامپوننت ChangeColorاکنون از Redux برای مدیریت state استفاده می‌کند. کاربران می‌توانند با تایپ رنگ دلخواه خود در قسمت input و کلیک بر روی دکمه «تغییر رنگ متن» رنگ متن نمایش داده شده را تغییر دهند.

اکنون کد کامل مدیریت state به شکل زیر می‌باشد:

import { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { changeColor } from '../features/Color';

const ChangeColor = () => {
  // State to hold the selected color
  const [color, setColor] = useState('');

  // Accessing the dispatch function from react-redux
  const dispatch = useDispatch();

  // Accessing the theme color value from the Redux store
  const themeColor = useSelector((state) => state.theme.value);

  // Event handler for the input change
  const handleColorChange = (e) => {
    setColor(e.target.value);
  };

  // Event handler for the button click
  const handleButtonClick = () => {
    // Dispatching the changeColor action with the selected color
    dispatch(changeColor(color));
  };

  return (
    <div style={{ color: themeColor }}>
      <p>Progressively effective resources via business metrics.</p>
      <br />
      <div className='inputBtn-container'>
        <input type='text' className='input' onChange={handleColorChange} />
        <button className='btn' onClick={handleButtonClick}>
          Change text color
        </button>
      </div>
    </div>
  );
};

export default ChangeColor;

جمع‌بندی

این مقاله دو راه حل برای مدیریت state را پوشش می دهد: هوک ()useState برای برنامه‌های کوچک تا متوسط و Redux برای برنامه‌های بزرگ‌تر است. برای انتخاب بهترین روش باید مواردی مانند پیچیدگی برنامه، اندازه تیم و نیازهای عملکردی را در نظر بگیریم. همچنین داشتن درک درست از نحوه کارکرد هر دو رویکرد به ما در انتخاب درست‌تر کمک می‌کند.

دیدگاه‌ها:

افزودن دیدگاه جدید