وقتی شروع به یادگیری Redux کردم، درک یک سری مفاهیم برایم چالش برانگیز بود. علیرغم خواندن بسیاری از منابع آنلاین، برای درک ایده های اصلی تلاش کردم.در حالی که آموزشها و راهنماهای آنلاین اطلاعات مفیدی را ارائه میکردند، برای درک واقعی Redux به وضوح بیشتری نیاز داشتم.اما با پشتکار و تمرین، در نهایت درک بهتری از مفاهیم کلیدی Redux به دست آوردم و آنها را با موفقیت در پروژه هایم پیاده سازی کردم.
در این مقاله Redux را به ساده ترین شکل ممکن توضیح خواهم داد. به عنوان کسی که در ابتدا با درک Redux مشکل داشت، می دانم که یادگیری یک مفهوم جدید چقدر می تواند خسته کننده باشد. اما امیدوارم این مقاله کمک کند تا مفاهیم Redux برای مبتدی ها قابل دسترس تر باشد.
ما همچنین به Redux Toolkit خواهیم پرداخت، مجموعه ای از ابزارهایی که با استفاده از Redux ساده می شوند. این ابزارها کمک می کنند تا Redux کمتر دلهره آور باشد و استفاده از آن آسان تر شود.
Redux چیست؟
Redux یک کتابخانه مدیریت state ها است که به شما امکان می دهد state های برنامه های جاوا اسکریپت خود را به طور کارآمدتر و قابل پیش بینی مدیریت کنید.
تصور کنید که در حال ساختن یک خانه هستید و باید تمام موادی که استفاده می کنید و مقدار پولی که خرج می کنید را پیگیری کنید. به جای پیگیری همه چیز در ذهن یا روی یک تکه کاغذ، می توانید از یک دفتر کل برای پیگیری هر معامله استفاده کنید. Redux به طور مشابه با پیگیری stateهای برنامه شما در یک مکان به نام "store" کار می کند.
فرض کنید در حال ساخت یک سایت تجارت الکترونیک هستید. ممکن است لازم باشد اقلام موجود در سبد خرید کاربر، اطلاعات پرداخت و جزئیات ارسال آنها را پیگیری کنید.
Redux بهجای انتقال این اطلاعات از کامپوننتی به کامپوننت دیگر با استفاده از لوازم، به شما امکان میدهد آنها را در یک مکان مرکزی ذخیره کنید، جایی که به راحتی قابل دسترسی و بهروزرسانی باشد. این امر مدیریت state های پیچیده و سازماندهی برنامه شما را آسان تر می کند.
ذکر این نکته ضروری است که Redux به React محدود نمی شود و می توانید از آن با فریمورک های دیگر یا حتی جاوا اسکریپت وانیلی استفاده کنید.
چرا باید از Redux استفاده کنم؟
Redux میتواند به سادهسازی فرآیند مدیریت state کمک کند، بهویژه زمانی که با کامپوننت های پیچیده و به هم مرتبط سروکار داریم. در اینجا دلایلی وجود دارد که چرا ممکن است بخواهید از Redux در برنامه خود استفاده کنید:
مدیریت state متمرکز: با Redux، میتوانید state کل برنامه خود را در یک store حفظ کنید و مدیریت و دسترسی به دادهها را در کامپوننت های مختلف آسانتر میکند.
بهروزرسانیهای state قابل پیشبینی: Redux جریان واضحی از دادهها دارد، به این معنی که تغییرات در state تنها زمانی اتفاق میافتد که شما اقدامی را ایجاد کرده و از طریق Redux ارسال کنید. این امر درک اینکه چگونه داده های برنامه شما در پاسخ به اقدامات کاربر تغییر می کند آسان می کند.
اشکال زدایی آسانتر: با Redux DevTools، شما یک رکورد واضح از تمام تغییرات در state برنامه خود دارید. این امر مکان یابی و رفع مشکلات را در کد شما آسان تر می کند و در زمان و تلاش شما در فرآیند اشکال زدایی صرفه جویی می کند.
عملکرد بهتر: Redux با به حداقل رساندن تعداد به روز رسانی های state و کاهش نیاز به prop، به بهبود عملکرد برنامه شما کمک می کند.
Redux چگونه کار می کند؟
همانطور که قبلا ذکر شد، Redux شما را قادر میسازد تا یک store متمرکز داشته باشید که state کل برنامه شما را مدیریت میکند. همه کامپوننت های برنامه شما می توانند به این store دسترسی داشته باشند و در صورت نیاز داده ها را از آن به روز کنند یا بازیابی کنند.
کامپوننتهای کلیدی که این رویکرد متمرکز را در مدیریت state ممکن میسازد عبارتند از:
State
اقدامات Actions
ارسال Dispatch
کاهنده ها Reducers
بیایید نقش هر یک را بررسی کنیم:
Store
استور Redux مانند یک ظرف غول پیکر است که تمام داده های برنامه شما را در خود نگه می دارد.
store را به عنوان جعبه ای با محفظه های مختلف برای انواع داده های مختلف در نظر بگیرید. شما می توانید هر داده ای را که می خواهید در این محفظه ها ذخیره کنید و می تواند انواع مختلفی از داده ها مانند رشته ها، اعداد، آرایه ها، اشیاء و حتی توابع را در خود جای دهد.
همچنین، store تنها منبع حقیقت برای state برنامه شما است. این بدان معناست که هر کامپوننت در برنامه شما می تواند برای بازیابی و به روز رسانی داده ها به آن دسترسی داشته باشد.
اقدامات Actions
یک Action شیئی است که توضیح می دهد چه تغییراتی باید در state برنامه شما ایجاد شود. این داده ها را از برنامه شما به store Redux ارسال می کند و به عنوان تنها راه برای به روز رسانی store عمل می کند.
یک عمل باید دارای ویژگی "نوع" باشد که عمل انجام شده را توصیف کند. این ویژگی "نوع" معمولاً به عنوان یک ثابت رشته برای اطمینان از ثبات و جلوگیری از اشتباهات تایپی تعریف می شود.
علاوه بر ویژگی "نوع"، یک اکشن می تواند دارای ویژگی "payload" نیز باشد. ویژگی "payload" نشان دهنده داده هایی است که اطلاعات اضافی در مورد عمل انجام شده ارائه می دهد. به عنوان مثال، اگر یک نوع اقدام ADD_TASK
باشد، ممکن است محموله یک شی حاوی "id"، "text" و "completed status" یک آیتم وظیفه جدید باشد.
در اینجا یک نمونه از یک عمل آورده شده است:
{
type: 'ADD_TASK',
payload: {
id: 1,
text: 'Buy groceries',
completed: false
}
}
توجه داشته باشید که برای ایجاد اکشن ها از Action Creators استفاده می کنیم. Action creators توابعی هستند که اشیاء اکشن را ایجاد و برمی گرداند.
در اینجا نمونه ای از یک اکشن ایجاد کننده است که متن یک کار را می گیرد و یک شی اکشن را برای اضافه کردن وظیفه به store Redux برمی گرداند:
function addTask(taskText) {
return {
type: 'ADD_TASK',
payload: {
id: 1,
text: taskText,
completed: false
}
}
}
یک قیاس مناسب برای اکشن ها و خالقان اکشن، سر آشپزی است که از دستور پخت استفاده می کند. دستور العمل مواد تشکیل دهنده و دستورالعمل های لازم برای تهیه یک غذا را تشریح می کند، مشابه اینکه چگونه یک عمل در Redux جزئیات مورد نیاز را برای تغییر state یک برنامه مشخص می کند.
در این سناریو، سرآشپز نماینده اکشن خالق است که دستور تهیه غذا را دنبال میکند، مشابه اینکه چگونه یک اکشن خالق اقدامی را بر اساس ویژگیهای از پیش تعریف شده ایجاد میکند.
ارسال Dispatch
در Redux، dispatch تابعی است که توسط store ارائه میشود و به شما امکان میدهد تا اقدامی برای بهروزرسانی state برنامه خود ارسال کنید. هنگامی که شما Dispatch را فرا میخوانید، store اقدامی را از طریق تمام Reducer های موجود انجام میدهد، که به نوبه خود state را مطابق با آن بهروزرسانی میکند.
میتوانید دیسپچ را بهعنوان یک حامل پستی در نظر بگیرید که نامهها را به بخشهای مختلف در یک شرکت بزرگ تحویل میدهد. درست مانند نحوه ارسال نامه توسط حامل نامه به بخش های مختلف، Dispatch نیز اقداماتی را به کاهش دهنده های مختلف در store Redux شما ارائه می دهد. هر کاهش دهنده مانند یک بخش در شرکت است که نامه ها را پردازش می کند و بخشی از داده های شرکت خود را به روز می کند.
کاهنده ها Reducer
در Redux، کاهنده تابعی است که state فعلی یک برنامه و یک عمل را به عنوان آرگومان می گیرد و یک state جدید را بر اساس عمل باز می گرداند.
در اینجا مثالی از یک کاهنده ساده آورده شده است:
const initialState = {
count: 0
};
function counterReducer(state = initialState, action) {
switch(action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
case 'DECREMENT':
return { ...state, count: state.count - 1 };
default:
return state;
}
}
در کد بالا یک کاهنده ساده به نام "counterReducer
" داریم که state یک متغیر count را مدیریت می کند. این دو آرگومان دارد: state
و action
. آرگومان state
نشان دهنده state فعلی برنامه شما است، در حالی که آرگومان action
نشان دهنده اقدامی است که برای تغییر state ارسال شده است.
سپس کاهنده از یک دستور switch برای بررسی "نوع" عمل استفاده می کند و بر اساس آن نوع، state را متناسب با آن به روز می کند.
به عنوان مثال، اگر نوع عمل "INCREMENT
" باشد، کاهنده یک شی state جدید را با تعداد افزایش 1 برمی گرداند. همچنین، اگر نوع عمل "DECREMENT
" باشد، کاهنده یک شی state جدید را با تعداد کاهش 1 برمی گرداند. .
یک قیاس کامل برای یک کاهنده می تواند مخلوط کن آشپزخانه باشد. درست همانطور که یک مخلوط کن مواد مختلف را می گیرد، آنها را مخلوط می کند و یک مخلوط صاف تولید می کند، یک کاهنده نیز در حالت فعلی یک کاربرد و یک عمل قرار می گیرد، آنها را با هم پردازش می کند و حالت جدیدی ایجاد می کند.
حال بریم یک پروژه واقعی را پیاده سازی کنیم با هم دیگر با این مواردی که گفته شد.
پروژه مثال - پیاده سازی واقعی برنامه
اکنون که اصول اولیه Redux و نحوه عملکرد آن را فهمیدید، بیایید یک پروژه ساده در دنیای واقعی ایجاد کنیم. برای این مثال، ما یک برنامه اصلی ToDo List ایجاد می کنیم که در آن می توانید وظایف را اضافه و حذف کنید.
مرحله 1: نحوه راه اندازی پروژه
با اجرای دستور زیر در ترمینال خود یک پروژه React جدید ایجاد کنید. نام پروژه خود را جایگزین "your-project-name
" کنید.
npm create vite@latest your-project-name -- --template react
cd your-project-name
npm install
دنباله دستور بالا با استفاده از ابزار Vite build یک پروژه React جدید ایجاد می کند و تمام وابستگی های لازم را نصب می کند. اگر با vite آشنا نیستید می توانید این مقاله وب سایت آنوفل درباره Vite را مطالعه کنید.
مرحله 2: نحوه نصب Redux
Redux برای عملیات خود به چند وابستگی نیاز دارد که عبارتند از:
Redux: کتابخانه هسته معماری redux را فعال می کند.
React Redux: اتصال کامپوننت های React شما به store Redux را ساده می کند.
Redux Thunk: به شما امکان می دهد منطق ناهمزمان را در اقدامات Redux خود بنویسید.
برنامه افزودنی Redux DevTools: برنامه Redux شما را به Redux DevTools متصل می کند
می توانید آنها را با استفاده از npm نصب کنید، همانطور که در زیر نشان داده شده است:
npm install \
redux \
react-redux \
redux-thunk \
redux-devtools-extension
مرحله 3: نحوه تنظیم کاهنده ها Reducers
حال بیایید کاهش دهنده را برای برنامه خود ایجاد کنیم.
در پوشه src
یک پوشه جدید به نام Reducers
ایجاد کنید و در داخل آن پوشه دو فایل جدید ایجاد کنید: index.js
و taskReducer.js
.
فایل index.js
نشان دهنده کاهش دهنده ریشه است که همه کاهنده های فردی را در برنامه ترکیب می کند. در مقابل، فایل taskReducer.js
یکی از کاهش دهنده های فردی است که در کاهش دهنده ریشه ترکیب می شود.
//index.js
import taskReducer from "./taskReducer";
import { combineReducers } from "redux";
const rootReducer = combineReducers({
tasks: taskReducer,
});
export default rootReducer;
در فایل index.js
بالا، ما از تابع combinationReducers
برای ترکیب همه کاهندهها در یک کاهنده ریشه استفاده میکنیم. در این مورد، ما فقط یک کاهش دهنده (taskReducer) داریم، بنابراین آن را به عنوان یک آرگومان به combinationReducers
ارسال می کنیم.
سپس کاهنده ترکیبی حاصل صادر میشود تا سایر فایلهای برنامه بتوانند وارد کرده و از آن برای ایجاد store استفاده کنند.
در اینجا کد taskReducer
آمده است:
//taskReducer.js
const initialState = {
tasks: []
};
const taskReducer = (state = initialState, action) => {
switch (action.type) {
case 'ADD_TASK':
return {
...state,
tasks: [...state.tasks, action.payload]
};
case 'DELETE_TASK':
return {
...state,
tasks: state.tasks.filter(task => task.id !== action.payload)
};
default:
return state;
}
};
export default rootReducer;
در فایل taskReducer.js
بالا، یک تابع کاهنده تعریف می کنیم که دو آرگومان می گیرد: state
و action
. آرگومان state
نشان دهنده state فعلی برنامه است، در حالی که آرگومان اقدام نشان دهنده اقدامی است که برای به روز رسانی state ارسال می شود.
دستور switch
در داخل کاهنده موارد مختلف را بر اساس "نوع" عمل کنترل می کند. به عنوان مثال، اگر نوع عمل ADD_TASK
باشد، کاهنده یک شی state جدید را با یک وظیفه جدید به آرایه وظایف اضافه میکند. و اگر نوع عمل DELETE_TASK
باشد، کاهنده یک شی state جدید را با وظایف فعلی فیلتر شده برای حذف کار با id
مشخص شده برمی گرداند.
مرحله 4: نحوه ایجاد store Redux
اکنون که تنظیمات اولیه خود را آماده کرده ایم، بیایید یک فایل جدید به نام store.js
در دایرکتوری src
ایجاد کنیم. اینجا جایی است که شما store Redux خود را تعریف می کنید:
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "redux-devtools-extension";
import taskReducer from "./reducers/taskReducer";
const store = createStore(
taskReducer,
composeWithDevTools(applyMiddleware(thunk))
);
export default store;
کد بالا یک store Redux را با ایجاد یک نمونه جدید از store با استفاده از تابع createStore
راه اندازی می کند. سپس، rootReducer
که تمام کاهش دهنده های برنامه را در یک کاهنده واحد ترکیب می کند - به عنوان آرگومان به createStore
ارسال می شود.
علاوه بر این، کد از دو کتابخانه دیگر نیز استفاده می کند: redux-thunk و redux-devtools-extension.
کتابخانه redux-thunk به شما امکان میدهد تا عملکردهای ناهمزمان بنویسید، در حالی که کتابخانه redux-devtools-extension به شما امکان میدهد از افزونه مرورگر Redux DevTools برای اشکالزدایی و بازرسی state و اقدامات موجود در store استفاده کنید.
در نهایت، store را export می کنیم تا بتوانیم از آن در برنامه خود استفاده کنیم. ما از تابع composeWithDevTools
برای ارتقای store با قابلیت استفاده از افزونه Redux DevTools و از تابع applicationMiddleware
برای اعمال میدلور thunk در store استفاده میکنیم.
مرحله 5: نحوه اتصال Redux Store به برنامه
برای اتصال store Redux به برنامه ToDo، باید از کامپوننت Provider از کتابخانه react-redux استفاده کنیم.
ابتدا تابع Provider و store Redux که ایجاد کردیم را به main.jsx
خود وارد می کنیم. سپس، کامپوننت App خود را با تابع Provider بسته بندی می کنیم و store را به عنوان یک پراپ قرار می دهیم. این باعث می شود که store Redux برای همه کامپوننت های داخل App
در دسترس باشد.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { Provider } from "react-redux";
import store from "./store";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
مرحله 6: نحوه استفاده از Redux DevTools
هنگامی که Redux Provider را در برنامه خود راه اندازی کردید، می توانید از افزونه Redux DevTools استفاده کنید. برای شروع کار با آن، باید افزونه Redux DevTools را برای مرورگر خود دانلود کنید.
پس از نصب، DevTools یک تب جدید به ابزارهای توسعه دهنده مرورگر شما به طور خاص برای Redux اضافه می کند.
با کلیک بر روی برگه State
در Redux DevTools، state کل store Redux شما و هر اقدامی که ارسال شده است و بارهای آنها را نشان می دهد.
این می تواند در هنگام اشکال زدایی برنامه شما بسیار مفید باشد، زیرا می توانید state و اقدامات را در زمان واقعی بررسی کنید.
مرحله 7: نحوه تنظیم Redux Actions
اکنون که همه چیز را آماده کرده ایم، بیایید اقدامات خود را ایجاد کنیم. همانطور که قبلا ذکر کردم، اقدامات نشان دهنده چیزی است که در برنامه اتفاق افتاده است. به عنوان مثال، هنگامی که یک کاربر یک کار جدید اضافه می کند، یک عمل "افزودن وظیفه" را راه اندازی می کند. به طور مشابه، هنگامی که یک کاربر یک کار را حذف می کند، یک عمل "حذف وظیفه" را آغاز می کند.
برای ایجاد اکشن ها، یک پوشه جدید به نام "actions
" در پوشه src
ایجاد کنید و سپس یک فایل جدید به نام index.js
ایجاد کنید. این فایل شامل تمام سازندگان اقدام برای برنامه ما خواهد بود.
export const addTodo = (text) => {
return {
type: "ADD_TASK",
payload: {
id: new Date().getTime(),
text: text,
},
};
};
export const deleteTodo = (id) => {
return {
type: "DELETE_TASK",
payload: id,
};
};
کد بالا دو سازنده اقدام را export می کند: addTodo
و deleteTodo
. این توابع یک شی را با خاصیت نوع برمی گرداند که عملی را که رخ داده است را توصیف می کند.
در مورد addTodo، ویژگی type روی "ADD_TASK
" تنظیم می شود که نشان می دهد یک کار جدید اضافه شده است. ویژگی payload حاوی یک شی با id و مقادیر متن وظیفه جدید است. شناسه با استفاده از متد جدید ()Date().getTime
تولید می شود و یک id منحصر به فرد بر اساس زمان فعلی ایجاد می کند.
در مورد deleteTodo، ویژگی type روی "DELETE_TASK
" تنظیم می شود که نشان می دهد یک کار حذف شده است. ویژگی payload حاوی id وظیفه ای است که باید حذف شود.
این سازندگان اکشن را میتوان با استفاده از متد ()dispatch
به store Redux فرستاد، که تابع کاهنده مربوطه را فعال میکند تا state برنامه را متناسب با آن بهروزرسانی کند.
مرحله 8: نحوه ارسال اقدامات
اکنون که اقدامات لازم را ایجاد کرده ایم، می توانیم به سمت ایجاد کامپوننت هایی برویم که این اقدامات را ارسال می کنند.
بیایید یک پوشه جدید به نام "components
" در دایرکتوری src
ایجاد کنیم. در داخل این پوشه، دو فایل جدید ایجاد خواهیم کرد: Task.jsx
و TaskList.jsx
.
کامپوننت Task.jsx
مسئول افزودن وظایف خواهد بود. اما قبل از ادامه، باید موارد زیر را در فایل وارد کنیم:
اقدام addTodo
: برای افزودن وظایف جدید به حالت.useDispatch
hook: برای ارسال اکشن addTodo.useRef
: به ما اجازه می دهد تا به عناصر HTML ارجاع دهیم.
import { useRef } from "react";
import { useDispatch } from "react-redux";
import { addTodo } from "../actions";
پس از وارد کردن این کامپوننت های ضروری، میتوانیم به نوشتن کد برای Task.jsx
ادامه دهیم.
const Task = () => {
const dispatch = useDispatch();
const inputRef = useRef(null);
function addNewTask() {
const task = inputRef.current.value.trim();
if (task !== "") {
dispatch(addTodo(task));
inputRef.current.value = "";
}
}
return (
<div className="task-component">
<div className="add-task">
<input
type="text"
placeholder="Add task here..."
ref={inputRef}
className="taskInput"
/>
<button onClick={addNewTask}>Add task</button>
</div>
</div>
);
};
export default Task;
در کد بالا یک کامپوننت متشکل از یک فیلد ورودی و یک دکمه ایجاد کردیم. هنگامی که کاربر بر روی دکمه "افزودن وظیفه" کلیک می کند، تابع addNewTask
اجرا می شود. این تابع از هوکuseRef
برای به دست آوردن مقدار فیلد ورودی استفاده می کند، هر فضای خالی اصلی یا انتهایی را حذف می کند و سپس اقدام addTodo
را با وظیفه جدید به عنوان بار ارسال می کند.
حال، بیایید به کامپوننت TaskList.jsx
برویم، که مسئول ارائه لیست وظایف و مدیریت حذف وظایف است. برای رسیدن به این هدف، باید موارد زیر را وارد کنیم:
هوک useSelector
دسترسی به حالت را از store Redux فراهم می کند.
اکشن deleteTodo
مسئول حذف یک کار از لیست وظایف در store Redux است.
import { useSelector, useDispatch } from "react-redux";
import { deleteTodo } from "../actions";
اکنون کدی را برای TaskList.jsx
می نویسیم که روی آرایه وظایف نگاشت می شود و هر وظیفه را رندر می کند:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { deleteTodo } from '../actions';
const TaskList = () => {
const tasks = useSelector((state) => state.tasks);
const dispatch = useDispatch();
const handleDelete = (id) => {
dispatch(deleteTodo(id));
};
return (
<div className="tasklist">
<div className="display-tasks">
<h3>Your tasks:</h3>
<ul className="tasks">
{tasks.map((task) => (
<li className="task" key={task.id}>
{task.text}
<button
className="delete-btn"
onClick={() => handleDelete(task.id)}
>
delete
</button>
</li>
))}
</ul>
</div>
</div>
);
};
export default TaskList;
در اینجا، کامپوننت روی هر وظیفه در آرایه وظایف حلقه زده و متن و یک دکمه حذف را نمایش می دهد. هنگامی که کاربر روی دکمه حذف کلیک می کند، تابع handleDelete
فراخوانی می شود و عمل deleteTodo
را با id کار به عنوان بار ارسال می کند.
در نهایت کامپوننت ها را در فایل App.jsx
خود وارد کرده و رندر کنید.
import Task from "./components/Task";
import TaskList from "./components/TaskList";
function App() {
return (
<div className="App">
<Task />
<TaskList />
</div>
);
}
export default App;
مرحله 9: یک ظاهر طراحی شده
برای استایل کردن، محتویات می توانید خودتان یک سری استایل دهی انجام دهید و در فایل index.css
خود قرار دهید. تمرکز این راهنما فقط بر روی عملکرد است و نه بر روی یک ظاهر طراحی.
نتیجه نهایی
پس از اجرای همه چیز، نتیجه نهایی برنامه ToDo List ما باید چیزی شبیه به این باشد:
میتوانیم با وارد کردن متون در قسمت ورودی و کلیک بر روی دکمه «افزودن وظیفه»، کارها را اضافه کنیم. همچنین میتوانیم با کلیک روی دکمه «حذف» در کنار هر کار، وظایف را حذف کنیم.
با استفاده از Redux DevTools می توان state و اقدامات برنامه را نیز به راحتی ردیابی و بازرسی کرد. این ویژگی به اشکال زدایی و درک نحوه عملکرد برنامه در زیر هود کمک می کند.
با آن، شما اکنون یک برنامه ToDo کاملاً کاربردی دارید که توسط Redux طراحی شده است.
در نهایت، مهم است که توجه داشته باشید که state یک برنامه در هنگام استفاده از Redux در حافظه ذخیره می شود. بنابراین، اگر کاربر صفحه را بازخوانی کند یا از برنامه دور شود، state از بین می رود.
بنابراین، برای حفظ اطلاعات حتی پس از خروج یا بستن صفحه توسط کاربر، باید آن اطلاعات را در جایی خارج از حافظه برنامه ذخیره کنید. برای انجام این کار می توان از تکنیک های مختلفی مانند ذخیره سازی محلی یا سمت سرور استفاده کرد.
تبریک می گویم! اکنون درک خوبی از نحوه ادغام Redux در برنامه های React خود دارید. در بخش بعدی، Redux Toolkit را بررسی خواهیم کرد و کشف خواهیم کرد که چگونه می تواند فرآیند نوشتن کد Redux را با تلاش کمتر ساده کند.
نحوه استفاده از Redux Toolkit
نوشتن کد Redux می تواند پیچیده و پرمخاطب شود، به خصوص با افزایش اندازه یک برنامه. با افزایش تعداد کاهش دهنده ها و اقدامات، مدیریت قطعات مختلف و پیگیری همه چیز می تواند چالش برانگیز شود.
خوشبختانه Redux Toolkit راه حلی برای این مشکل ارائه می دهد. با حذف برخی از جنبههای پیچیدهتر و تکراریتر Redux، مانند ایجاد کاهندهها و اقدامات، راه سادهتر و کارآمدتری برای مدیریت state برنامهتان ارائه میکند.
مزایای Redux Toolkit
Redux Toolkit چندین مزیت نسبت به Redux سنتی دارد:
راه اندازی آن آسان تر است و به وابستگی های کمتری نیاز دارد.
کد با اجازه دادن به ایجاد یک فایل منفرد به نام "slice
" که اقدامات و کاهش دهنده ها را ترکیب می کند، کاهش می دهد.
پیشفرضهای معقولی را برای ویژگیهای معمولی مانند Redux Thunk و Redux DevTools ارائه میکند. این بدان معناست که نیازی به صرف زمان برای پیکربندی این ویژگیها ندارید، زیرا آنها قبلاً در Redux Toolkit ساخته شدهاند.
از کتابخانه immer
زیر هود استفاده می کند که جهش مستقیم حالت را فعال می کند و نیاز به کپی دستی استیت {...state} با هر کاهنده را از بین می برد.
در بخشهای بعدی، نحوه استفاده از Redux Toolkit را برای سادهسازی کد Redux برای برنامه ToDo که قبلاً ساختیم، بررسی خواهیم کرد.
نحوه راه اندازی Redux Toolkit
برای استفاده از Redux Toolkit در برنامه React خود، باید دو وابستگی را نصب کنید: reduxjs/toolkit@
و react-redux
.
پکیج reduxjs/toolkit@
ابزارهای لازم را برای ساده سازی توسعه Redux فراهم می کند، در حالی که react-redux
برای اتصال store Redux شما به کامپوننت های React شما مورد نیاز است.
npm install @reduxjs/toolkit react-redux
چگونه یک Slice ایجاد کنیم
هنگامی که وابستگی های مورد نیاز را نصب کردید، با استفاده از تابع createSlice
یک "Slice" جدید ایجاد کنید. Slice بخشی از store Redux است که مسئول مدیریت یک بخش خاص از state است.
store Redux را به عنوان یک کیک در نظر بگیرید، جایی که هر برش نشان دهنده یک قطعه خاص از داده در store است. با ایجاد یک برش، می توانید رفتار state را در پاسخ به اقدامات خاص با استفاده از توابع کاهنده تعریف کنید.
برای ایجاد یک برش برای مدیریت برنامه ToDo ما، یک فایل جدید با نام src/features/todo/todoSlice.js
ایجاد کنید و کد زیر را اضافه کنید.
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
tasks: [],
};
const todoSlice = createSlice({
name: "todo",
initialState,
reducers: {
addTodo: (state, action) => {
state.tasks.push({ id: Date.now(), text: action.payload });
},
deleteTodo: (state, action) => {
state.tasks = state.tasks.filter((task) => task.id !== action.payload);
},
},
});
export const { addTodo, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
کد بالا یک slice به نام todoSlice
را با یک شی inicialState
که حاوی یک آرایه خالی از وظایف است، تعریف می کند.
شی کاهش دهنده دو تابع کاهنده را تعریف می کند: addTask
و addTask
. deleteTask
یک شیء وظیفه جدید را به آرایه وظایف فشار می دهد و deleteTask
یک وظیفه را بر اساس ویژگی id آن از آرایه وظایف حذف می کند.
تابع createSlice
به طور خودکار بر اساس نام توابع کاهشدهندهای که ارائه میدهید، سازندههای اقدام و انواع کنشها را تولید میکند. بنابراین لازم نیست خودتان اکشن سازان را به صورت دستی تعریف کنید.
بیانیه export ، سازندگان اقدام تولید شده را export میکند، که میتوانند در قسمتهای دیگر برنامه شما برای ارسال کنشها به بخش استفاده شوند.
و در نهایت، تابع todoSlice.reducer
تمام اقدامات تولید شده به طور خودکار بر اساس اشیاء کاهش دهنده ارائه شده به تابع createSlice
را کنترل می کند. با export آن به عنوان پیشفرض، میتوانید آن را با کاهشدهندههای دیگر در برنامه خود ترکیب کنید تا یک store Redux کامل ایجاد کنید.
نحوه راه اندازی Redux Store
ایجاد یک store Redux با Redux Toolkit بسیار ساده تر است.
ابتدایی ترین راه برای ایجاد یک store استفاده از تابع ()configureStore
است که به طور خودکار با ترکیب همه کاهنده های تعریف شده در برنامه شما یک کاهش دهنده ریشه برای شما ایجاد می کند.
برای ایجاد store برای برنامه، فایلی به نام src/store.js
اضافه کنید و کد زیر را اضافه کنید:
import { configureStore } from "@reduxjs/toolkit";
import todoReducer from "./features/todo/todoSlice";
const store = configureStore({
reducer: {
todo: todoReducer,
},
});
export default store;
در این مثال، ابتدا تابع configureStore
را از پکیج reduxjs/toolkit@
و تابع todoReducer
را از یک فایل جداگانه وارد می کنیم.
سپس، با فراخوانی configureStore
و ارسال یک شی با ویژگی کاهش دهنده، یک شی store ایجاد می کنیم. خاصیت کاهنده شی ای است که نام برش های کاهنده را به توابع کاهنده مربوطه نگاشت می کند. در این حالت، یک برش کاهنده به نام todo داریم و تابع کاهنده مربوط به آن todoReducer است.
در نهایت شی store را اکسپورت می کنیم تا بتوان آن را وارد کرد و در قسمت های دیگر برنامه استفاده کرد.
نحوه ارائه store Redux به React
برای اینکه store Redux خود را در اختیار کامپوننتهای React در برنامه خود قرار دهید، کامپوننت Provider را از کتابخانه react-redux وارد کنید و کامپوننت ریشه (معمولاً <App>
) را با آن بپیچید.
کامپوننت Provider در استور بهعنوان یک پایه استفاده میکند و آن را به تمام کامپوننتهای فرزندی که نیاز به دسترسی به آن دارند، منتقل میکند.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
import "./index.css";
import store from "./store.js";
import { Provider } from "react-redux";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
کامپوننت ایجاد کنید
اکنون می توانید کامپوننت های React مانند Task.jsx
و TaskList.jsx
را ایجاد کنید که از هووک useSelector
برای دسترسی به state فعلی از store استفاده می کنند. به طور مشابه، میتوانید از هووک useDispatch
برای ارسال اقدامات برای بهروزرسانی store استفاده کنید، همانطور که در Redux ساده انجام دادید.
اکنون باید همان برنامه قبلی را با چند به روز رسانی از Redux Toolkit و کد بسیار کمتری برای نگهداری داشته باشید.
نتیجه
اگر این آموزش را دنبال کرده اید، اکنون باید درک کاملی از Redux داشته باشید، هم رویکرد سنتی و هم نسخه ساده شده با استفاده از Redux Toolkit.
امیدوارم این مقاله برای شما مفید و آموزنده بوده باشد. می دانم که مطالب زیادی برای پوشش دادن بود، اما امیدوارم به عنوان یک منبع جامع برای مبتدی ها و متوسط که به دنبال یادگیری Redux هستند، باشد.
با تشکر از شما برای خواندن، و هر گونه سوالی داشتید می توانید در قسمت نظرات بپرسید.