مدیریت state برای مدیریت دادههای یک برنامه، نحوه تعامل کاربران با آن و نحوه رفتار بخشهای مختلف برنامه بسیار مهم است. مدیریت state چیزی نیست که فقط در React از آن استفاده کنیم، بلکه در ابزارهای محبوب دیگر مانند Angular.js، Vue.js و Next.js نیز مورد استفاده قرار میگیرد. دو راه متداول برای مدیریت state وجود دارد: ()useState و Redux. اما گزینههای دیگری مانند MobX، Zustand و Recoil نیز هستند.
در این مقاله قصد داریم تا با مدیریت state و چرایی اهمیت آن آشنا شویم. همچنین روشهای رایج مدیریت state را بررسی و نحوه عملکرد آنها را درک خواهیم کرد. پس از خواندن این مقاله، میتوانیم بهترین روش مدیریت state را برای برنامه خود انتخاب کنیم.
مدیریت state بخش مهمی از توسعه برنامه است. این کار به برنامه نویسان اجازه میدهد تا نحوه واکنش برنامه به رویدادهای مختلف و اقدامات کاربر را کنترل کنند. همچنین کمک میکند تا رابطهای کاربری پویا و تعاملی ایجاد کرده و تجربه کاربری بهتری داشته باشیم.
مدیریت state در بسیاری از وب سایتها و برنامهها، از ساده تا پیچیده، مورد استفاده قرار میگیرد. React و فریمورکهایی مانند Angular.js، Vue.js و Next.js اغلب از مدیریت state برای مدیریت دادهها و کنترل نحوه رفتار کامپوننتها استفاده میکنند.
برای درک بهتر مدیریت state، میخواهیم یک مثال عملی را باهم بررسی کنیم که نشان میدهد هوک ()useState و Redux چگونه در React کار میکنند.
ابتدا به پوشه پروژه میرویم. با استفاده از دستور create-react-app
یا ابزار Vite یک React boilerplate ایجاد میکنیم. ما در این مقاله از vite استفاده میکنیم، زیرا برای توسعه سریعتر است و پیکربندی آسانی دارد. Vite همچنین کارایی بیشتری دارد و از دیگر فریم ورکهای فرانتاند مانند Svelte پشتیبانی میکند.
سپس در ادیتور دستور زیر را وارد میکنیم:
npx create-react-app ./ or npx create-vite@latest ./
./
React boilerplate را درست داخل پوشه یا دایرکتوری ایجاد شده برای ما میسازد.
()useState یک هوک داخلی در React است و state برنامههای React را به صورت local مدیریت میکند. هوک ()useState همچنین قابلیتهای مدیریت state را در فانکشنال کامپوننتها معرفی میکند. این بدان معناست که اکنون میتوانیم از منطق stateful در فانکشنال کامپوننتها استفاده کنیم.
در React، ما به هوکهای مختلف دیگری دسترسی داریم که میتوانیم آنها را import کرده و در برنامههای خود استفاده کنیم. این هوکها برنامه ما را پویاتر و کارآمدتر میکند.
میخواهیم برنامهای بسازیم که رنگ یک متن را بر اساس ورودی کاربر تغییر دهد. به عنوان مثال اگر inputای که کاربر وارد میکند red باشد، رنگ متن به قرمز تغییر پیدا کند.
استفاده از ()useState شامل یک فرآیند ساده است:
'react'
import میکنیم.به عنوان مثال:
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
به آنچه کاربر تایپ میکند تغییر مینماید.
Redux یک کتابخانه جاوااسکریپت برای مدیریت stateها در برنامهها است که با React و سایر فریمورکها کار میکند. این کتابخانه به ما کمک میکند تا global state برنامه خود را مدیریت کنیم. علاوه بر این، عملکرد برنامه را نیز بهبود میبخشد.
همچنین میتوانیم 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 در سراسر برنامه در دسترس باشد.
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 برای مدیریت state استفاده کنیم. ابتدا پوشهای به نام components
میسازیم. داخل آن پوشه، فایلی به نامChangeColor.jsx
ایجاد میکنیم.
در دایرکتوری پروژه خود، یک پوشه با نام features
ایجاد میکنیم. داخل این پوشه، فایلی به نام Color.js
ایجاد مینماییم تا منطق Redux را برای برنامه ما نگه دارد.
در مرحله بعد، میخواهیم به کاربران اجازه دهیم تا رنگ مورد نظر خود را وارد کنند. برای انجام این کار، هوک ()useState را به صورت زیر در فایل ChangeColor.jsx
import میکنیم:
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-redux
import میکنیم تا actionها را به Redux store ارسال کنیم. به این ترتیب میتوانیم مقدار رنگ را در state بهروزرسانی کنیم.Color.js
را که حاوی منطق Redux و شامل reducer و action تغییر رنگ است، import میکنیم.به این ترتیب:
useSelector
از 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 برای برنامههای بزرگتر است. برای انتخاب بهترین روش باید مواردی مانند پیچیدگی برنامه، اندازه تیم و نیازهای عملکردی را در نظر بگیریم. همچنین داشتن درک درست از نحوه کارکرد هر دو رویکرد به ما در انتخاب درستتر کمک میکند.