آیا بین useState و useReducer در React اشتباه گرفته اید؟ بهترین قلاب مدیریت دولتی برای نیازهای خود را در این راهنمای مفید کشف کنید.
اگر می خواهید یک شغل توسعه وب بیابید، اگر کتابخانه React JavaScript را یاد بگیرید شانس بیشتری برای موفقیت خواهید داشت. React یکی از پرکاربردترین کتابخانه ها در صنعت است. و یکی از جالب ترین ویژگی های کتابخانه React مفهوم قلاب است.
هوک ها به سادگی توابع جاوا اسکریپت هستند که به شما امکان می دهند منطق را در یک برنامه React مجدداً استفاده کنید. برای مدیریت حالت، دو قلاب اصلی در دسترس شما وجود دارد – قلاب useState و قلاب useReducer.
مروری بر useState Hook
قلاب useState رایجترین راه برای مدیریت وضعیت در React است. نحو زیر نحوه استفاده از این قلاب را در برنامه خود نشان می دهد:
const [state, setState] = useState(initialStateValue);
در بلوک کد بالا، متغیر حالت داده ها را بین رندرها در حافظه نگه می دارد. و setState تابع “setter” است که متغیر حالت را دستکاری می کند.
قلاب useState آرایه ای را دقیقاً با دو عنصر برمی گرداند. همچنین یک مقدار اولیه برای متغیر state می گیرد.
به عنوان مثال، اگر می خواهید یک متغیر حالت تعریف کنید که نشان دهنده سن کاربر با مقدار اولیه 17 باشد، به این صورت این کار را انجام می دهید:
const [userAge, setUserAge] = useState(17);
تابع setUserAge مسئول تغییر متغیر وضعیت userAge است.
setUserAge(19);
مهم است که توجه داشته باشید که به روز رسانی وضعیت، باعث ایجاد مجدد رندر کامپوننت می شود و به روز رسانی نامناسب متغیر حالت می تواند منجر به ایجاد یک حلقه نامحدود شود که می تواند کد شما را خراب کند.
در React توصیه نمیشود که وضعیت را مستقیماً تغییر دهید (همانطور که در بلوک کد زیر نشان داده شده است)، زیرا تغییرات در متغیرهای غیر حالت بین رندرهای مؤلفهها ادامه نمییابد.
userAge = 19;
حالت محلی برای مؤلفه ای است که آن را تعریف می کند. اگر اجزای یکسانی را چندین بار بر روی صفحه نمایش رندر کنید، هر جزء حالت مستقل خود را خواهد داشت.
function App(){
return (
<div>
<Switch />
<Switch />
</div>
)
}
در بلوک کد بالا، دو جزء Switch وجود دارد، اما هر کامپوننت حالت خود را مدیریت می کند و به مؤلفه دیگر متکی نیست مگر اینکه یکی از مؤلفه ها حالت خود را با مؤلفه دیگر به اشتراک بگذارد.
React بهروزرسانیهای حالت را با دستهبندی کنترل میکند. این بدان معناست که وقتی تابع تنظیم کننده متغیر حالت را فرا می خوانید، متغیر حالت تا رندر بعدی بعدی به روز نمی شود.
نمای کلی از useReducer Hook
useReducer یک قلاب React است که هر زمان که بخواهید چندین حالت مرتبط را به طور همزمان مدیریت کنید، می تواند به شما کمک کند. سینتکس useReducer چیزی شبیه به این است:
const [state, dispatch] = useReducer(reducer, initialState)
در مقایسه با useState، در useReducer، یک متغیر حالت و یک تابع اعزام وجود دارد که اقدامات را به تابع کاهنده ارسال می کند که بارها را مدیریت می کند و وضعیت را به روز می کند.
به عنوان مثال، فرض کنید که شما در حال ساخت یک برنامه شمارنده ساده با دکمه هایی هستید که می تواند شمارنده را بازنشانی کند، مقدار شمارنده را افزایش دهد یا مقدار شمارنده را کاهش دهد. با استفاده از useState کد شما چیزی شبیه به این خواهد بود:
function Counter(){
const [count, setCount] = useState(0);
return(
<div>
The count is: {count}
<div>
<button onClick={() => setCount(count + 1)}>Increase count</button>
<button onClick={() => setCount(0)}>Reset</button>
<button onClick={() => setCount(count - 1)}>Decrease Count</button>
</div>
</div>
)
}
اجرای فوق کاملاً کار می کند. اما می توانید با کمک قلاب useReducer نیز به نتایج مشابهی دست پیدا کنید.
این مثال صرفاً برای نشان دادن نحوه عملکرد قلاب useReducer است. در یک برنامه دنیای واقعی، useReducer برای این سناریو بیش از حد است.
useReducer مدیریت حالت های مرتبط و منطق پیچیده را بر اساس نوع ارسال شده در شی اکشن ارسال شده آسان می کند.
به عنوان مثال، تابع dispatch می تواند یک شیء عملی را ارسال کند که چیزی شبیه به این است:
{type:"action_type", payload:state * 2}
ابتدا قلاب useReducer را وارد کنید، سپس تابع کاهنده را با پارامترهای: state و شیء عمل تخریب شده تعریف کنید.
import {useReducer} from "react";
function reducer(state, { type, payload }) {
if (type === 'countIncrease') {
return payload;
} else if (type === 'countDecrease') {
return payload;
} else if (type === 'countReset') {
return payload;
} else {
return state;
}
}
پس از تعریف تابع کاهنده، می توانید کامپوننت Counter را با قلاب useReducer بسازید.
function Counter() {
const [count, dispatch] = useReducer(reducer, 0);
return (
<div>
The count is: {count}
<div>
<button onClick={() => dispatch({ type: 'countIncrease', payload: count + 1 })}>
Increase count
</button>
<button onClick={() => dispatch({ type: 'countReset', payload: 0 })}>
Reset count
</button>
<button onClick={() => dispatch({ type: 'countDecrease', payload: count - 1 })}>
Increase count
</button>
</div>
</div>
);
}
در بلوک کد بالا، اولین دکمه یک عمل از نوع countIncrease را با یک بار count + 1 ارسال می کند. این عمل مسئول افزایش مقدار شمارش است.
دکمه دوم یک عمل از نوع countReset را با بار 0 ارسال می کند که مقدار شمارش را به 0 بازنشانی می کند.
دکمه سوم یک عمل از نوع countDecrease را با باری از count – 1 ارسال می کند که مقدار شمارش را 1 کاهش می دهد.
انتخاب بین useState و useReducer Hooks
اکنون که نحوه استفاده از قلابهای useState و useReducer را میدانید، مهم است که بدانید چه زمانی از قلاب مناسب استفاده کنید.
اگر حالت شما به منطق پیچیده نیاز ندارد، واضح است که استفاده از useReducer می تواند بیش از حد باشد.
اگر حالت شما چیزی جز موارد اولیه جاوا اسکریپت مانند اعداد، رشته ها و مقادیر بولی است، باید از قلاب useState استفاده کنید. و اگر نوع حالت یک شی یا یک آرایه است، باید به جای آن از useReducer استفاده کنید.
با افزایش پیچیدگی برنامه شما، کنترل وضعیت فقط با قلاب useState و useReducer دشوار می شود.
این زمانی است که می توانید از کتابخانه های خارجی مانند Redux، Jotai و Zustand استفاده کنید. این کتابخانه ها مدیریت تغییرات حالت را در چندین مؤلفه آسان تر می کنند.
آسانتر کردن مدیریت دولتی با کتابخانههای جاوا اسکریپت
کتابخانههایی مانند React، Vue، و Svelte همگی روشهای خاص خود را برای مدیریت وضعیت دارند. مدیریت وضعیت به تنهایی با جاوا اسکریپت وانیلی قطعاً چیزی است که می توانید امتحان کنید، اما استفاده از کتابخانه جاوا اسکریپت آزمایش شده در نبرد بسیار ساده تر و راحت تر است.
اگر در حال ساخت یک برنامه پیچیده با استفاده از React هستید که در آن باید چندین مؤلفه را مدیریت کنید، Redux ممکن است بهترین انتخاب برای شما باشد.