آنچه در این مقاله میخوانید
۴ اشتباه رایج در هنگام استفاده از useState در ری اکت React
۳۰ فروردین ۱۴۰۴
ری اکت (React) یکی از محبوبترین ابزارهای توسعه وب است که به دلیل نحوه خاصی که در مدیریت وضعیت (state) داخل کامپوننتها دارد، محبوبیت زیادی پیدا کرده و مورد استفاده قرار میگیرد. یکی از هوکهای مهم در ری اکت، useState
است.
این هوک در ظاهر ساده به نظر میرسد، اما بسیاری از توسعهدهندگان، حتی کسانی که تجربه کافی دارند، ممکن است در موقع استفاده از آن دچار اشتباهاتی شوند. باید در نظر داشت که این اشتباهات میتوانند باعث بروز مشکلاتی در عملکرد اپلیکیشنها شوند.
در این مطلب از لیارا قصد داریم که به چهار اشتباه اصلی و رایج در استفاده از useState
در ری اکت React بپردازیم و نحوه جلوگیری از آنها را بررسی کنیم.
همین الان، هاست ابری React را با سرعت بالا راهاندازی کنید.
✅ بدون نیاز به پیکربندی ✅ استقرار آسان ✅ مناسب برای React
خرید هاست React
“برای ساخت برنامه React میتوانید از مستندات لیارا استفاده کنید.”
آنچه در ادامه خواهید خواند:
- خلاصه از از ری اکت
- 4 اشتباه رایج در هنگام استفاده از
useState
در React - سوالات متداول
- جمع بندی

خلاصه از از ری اکت
ری اکت یک کتابخانه متن باز جاوا اسکریپت است که اولین بار در سال 2013 توسط تیمی از توسعهدهندگان شرکت فیسبوک معرفی شد. این ابزار برای ساخت رابطهای کاربری (UI) طراحی شده است و به برنامهنویسان فرانت کمک میکند که اجزای صفحات وب را سریع، ساختارمند و با قابلیت استفاده مجدد طراحی کنند.
در ری اکت، دو اصطلاح کتابخانه و فریمورک اغلب به کار میرود. اگرچه ممکن است در ظاهر مشابه باشند، اما هر کدام از آنها در مفهوم تفاوتهایی دارند.
کتابخانهها معمولاً مجموعهای کمحجم و منعطف از کدهای آماده هستند که وظایف خاصی را انجام میدهند و میتوان مجدداً از آنها استفاده کرد. در مقابل، فریمورکها ساختاری کامل و گستردهتر هستند که نحوه نوشتن و سازماندهی کدها را تا حد زیادی مشخص میکنند.
ری اکت از این نظر ابزار منحصری است، زیرا میتوان بهصورت همزمان از برخی از ویژگیهای کتابخانه و فریمورکها استفاده کرد. از سوی دیگر، بسیار راحت و منعطف است و تنها بر بخش رابط کاربری تمرکز دارد. همچنین قابلیت گسترش و استفاده در پروژههای سختتر را فراهم میکند. به همین ترتیب، ری اکت به یکی از محبوبترین و پرکاربردترین ابزارهای توسعه رابط کاربری در دنیا تبدیل شده است.
مطالعه بیشتر: کار با hookها در React
4 اشتباه رایج در هنگام استفاده از useState
در React
شناخت این اشتباهات به شما کمک میکند که اپلیکیشنهای بهتری را بسازید و تجربه کار با ری اکت را برای خود سادهتر و بهینهتر کنید. تا انتهای این مطلب با ما همراه باشید.
اشتباه اول: نادیده گرفتن مقدار قبلی
یکی از اشتباهاتی که هنگام استفاده از هوک (Hook) در ری اکت رخ میدهد، نادیده گرفتن و فراموش کردن وضعیت قبلی زمان بهروزرسانی است. این اشتباه میتواند باعث بروز رفتارهای غیرمنتظره شود، مخصوصا در زمانهایی که بهروزرسانی سریع یا چندگانه صورت میگیرد.
درک این مشکل: فرض کنید که در حال ساخت یک شمارنده در ری اکت هستید و هدف اصلی شما این است که هر بار با کلیک بر روی دکمه، شمارش یک عدد افزایش پیدا کند. یک رویکرد ساده ممکن است این باشد که فقط 1 را به مقدار فعلی وضعیت اضافه کنید. اما این کار میتواند برای شما مشکلساز باشد.
import React, { useState } from 'react';
const CounterComponent = () => {
const [counter, setCounter] = useState(0);
const incrementCounter = () => {
setCounter(counter + 1); // Might not always work as expected
};
return (
<div>
<p>Counter: {counter}</p>
<button onClick={incrementCounter}>Increment</button>
</div>
);
};
export default CounterComponent;
در کد بالا، تابع incrementCounter
شمارنده را بر اساس مقدار فعلی آن بهروزرسانی میکند. این موضوع به نظر ساده میآید، اما میتواند مشکلات بزرگی برای شما به وجود بیاورد. ری اکت ممکن است چندین بار فراخوانی setCounter
را با هم گروهبندی کند یا بهروزرسانیهای دیگر وضعیتها ممکن است با هم تداخل پیدا کنند و در نتیجه باعث میشود شمارندهها هر بار به درستی بهروزرسانی نشوند.
حل مشکل: برای اینکه بتوانید از این مشکل جلوگیری کنید، باید از فرم تابعی متد setCounter
استفاده کنید. این نسخه یک تابع را به عنوان آرگومان دریافت میکند که در ری اکت آن را با جدیدترین مقدار وضعیت فراخوانی میکند و به شما این اطمینان را میدهد که همیشه با آخرین مقدار وضعیت کار میکنید.
import React, { useState } from 'react';
const CounterComponent = () => {
const [counter, setCounter] = useState(0);
const incrementCounter = () => {
setCounter(prevCounter => prevCounter + 1); // Correctly updates based on the most recent state
};
return (
<div>
<p>Counter: {counter}</p>
<button onClick={incrementCounter}>Increment</button>
</div>
);
};
export default CounterComponent;
در کد بالا، incrementCounter
از یک تابع برای بهروزرسانی وضعیت استفاده میکند. این تابع جدیدترین وضعیت، که در این کد prevCounter
است، را دریافت کرده و وضعیت بهروزرسانیشده را برمیگرداند. این رویکرد قابلاطمینان است و میتوان برای بهروزرسانیهای سریع یا مکرر از آن استفاده کرد.
برای ادامه مطالعه و یادگیری: آموزش راهاندازی برنامه React با NGINX در Docker
اشتباه دوم: تغییر دادن مستقیم state بهجای ساختن نسخهی جدید
در ری اکت، وضعیت باید بهعنوان یک شی تغییرناپذیر (immutable) در نظر گرفته شود. یکی از اشتباهات رایج، تغییر مستقیم وضعیت است، به خصوص زمانی که با ساختار دادههای پیچیده مانند اشیاء و آرایهها کار میشود.
import React, { useState } from 'react';
const ProfileComponent = () => {
const [profile, setProfile] = useState({ name: 'John', age: 30 });
const updateAge = () => {
profile.age = 31; // Directly mutating the state
setProfile(profile);
};
return (
<div>
<p>Name: {profile.name}</p>
<p>Age: {profile.age}</p>
<button onClick={updateAge}>Update Age</button>
</div>
);
};
export default ProfileComponent;
این کد به صورت اشتباه شی profile
را مستقیماً تغییر میدهد. چنین تغییراتی باعث میشود که ری اکت دوباره کامپوننت را رندر کند و همین امر منجر به رفتارهای غیرمنتظره میشود.
حل مشکل: برای اینکه بتوانید از این مشکل جلوگیری کنید، همیشه هنگام بهروزرسانی وضعیت، یک شی یا آرایه جدیدی بسازید تا تغییرناپذیری وضعیت حفظ شود. برای این کار میتوانید از اپراتور اسپرد (spread operator) استفاده کنید.
import React, { useState } from 'react';
const ProfileComponent = () => {
const [profile, setProfile] = useState({ name: 'John', age: 30 });
const updateAge = () => {
setProfile({...profile, age: 31}); // Correctly updating the state
};
return (
<div>
<p>Name: {profile.name}</p>
<p>Age: {profile.age}</p>
<button onClick={updateAge}>Update Age</button>
</div>
);
};
export default ProfileComponent;
در کد بالا، updateAge
با استفاده از اپراتور اسپرد (spread operator)، یک شی جدید از profile
میسازد که مقدار سن را در آن بهروزرسانی میکند. به این ترتیب، اصل تغییرناپذیری وضعیت (state immutability) حفظ میشود.
مطالعه بیشتر: معرفی هاست رایگان React
اشتباه سوم: درک نا درست از به روز رسانی های غیر هم زمان
بهروزرسانی وضعیت در ری اکت با استفاده از useState
به صورت غیرهمزمان (asynchronous) انجام میشود. این موضوع معمولاً باعث میشود که شما دچار سردرگمی شوید، مخصوصا در زمانی که چند بهروزرسانی پشت سر هم انجام میشود. بسیاری از توسعهدهندگان انتظار دارند که وضعیت بلافاصله بعد از فراخوانی setState
تغییر کند، اما در واقعیت، ری اکت برای بهبود عملکرد، تمامی این بهروزرسانیها را با هم گروهبندی (batch) میکند.
import React, { useState } from 'react';
const AsyncCounterComponent = () => {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(count + 1);
setCount(count + 1);
// Developer expects count to be incremented twice
};
return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment Count</button>
</div>
);
};
export default AsyncCounterComponent;
در این مثال، توسعهدهنده قصد دارد که مقدار شمارنده را به جای یک بار، دوبار افزایش دهد. اما به دلیل غیرهمزمان بودن بهروزرسانی وضعیت در ری اکت، هر دو فراخوانی setCount
بر اساس یک مقدار اولیه انجام میشود. در نتیجه شمارندهها فقط یک بار افزایش پیدا میکنند.
حل مشکل: برای اینکه بهروزرسانی غیرهمزمان به درستی و اصولی انجام شود، باید از فرم تابعی setCount
استفاده کنید. این روش به شما اطمینان میدهد که هر بهروزرسانی بر اساس جدیدترین مقدار وضعیت انجام میشود.
import React, { useState } from 'react';
const AsyncCounterComponent = () => {
const [count, setCount] = useState(0);
const incrementCount = () => {
setCount(prevCount => prevCount + 1);
setCount(prevCount => prevCount + 1);
// Now each update correctly depends on the most recent state
};
// Optional: Use useEffect to see the updated state
useEffect(() => {
console.log(count); // 2
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment Count</button>
</div>
);
};
export default AsyncCounterComponent;
در کد بالا، هر بار که setCount
فراخوانی میشود، از جدیدترین مقدار وضعیت استفاده میکند. این کار باعث میشود که بهروزرسانیها دقیق و به ترتیب انجام شود. چنین رویکردی برای عملیاتهایی که به مقدار فعلی وضعیت وابسته هستند، مخصوصا در شرایطی که چند بهروزرسانی پشت سر هم انجام میشود، اهمیت زیادی دارد.
همین الان، بدون کمترین پیچیدگی، سرور مجازی خودتون رو در کمتر از ۳۰ ثانیه، راهاندازی کنید.
✅ عملکرد پایدار ✅ ترافیک نامحدود ✅ هزینه بهصرفه
خرید سرور مجازی ابری
اشتباه چهارم: استفاده نادرست از state برای داده های قابل محاسبه
یکی از اشتباهاتی که بیشتر در این زمینه اتفاق میافتد، استفاده از state
برای نگهداری دادهها است. این موضوع میتواند از وضعیت یا props
موجود به دست بیاید. این نوع props
های تکراری نهتنها غیرضروری هستند، بلکه کدها را پیچیده کرده و ممکن است باعث بروز خطا شوند.
به عنوان نمونه:
import React, { useState } from 'react';
const GreetingComponent = ({ name }) => {
const [greeting, setGreeting] = useState(`Hello, ${name}`);
return (
<div>{greeting}</div>
);
};
export default GreetingComponent;
در این مثال، استفاده از state
برای مقدار greeting
بسیار ضروری است، به این دلیل که این مقدار میتواند مستقیماً از name
به دست آید.
حل مشکل: به جای ذخیره کردن چنین دادههایی در state
، آنها را مستقیماً از وضعیت یا props
موجود محاسبه کنید.
import React from 'react';
const GreetingComponent = ({ name }) => {
const greeting = `Hello, ${name}`; // Directly derived from props
return (
<div>{greeting}</div>
);
};
export default GreetingComponent;
در این قطعه کد، مقدار greeting
مستقیماً از prop
مربوط به name
محاسبه میشود. این کار باعث میشود که کامپوننتها سادهتر شوند و از مدیریت غیرضروری state
جلوگیری کند.
بیشتر بخوانید: آموزش راهاندازی اپلیکیشن وب Go با Docker و Nginx در اوبونتو 22.04
سوالات متداول
در ادامه به سوالاتی که امکان دارد در این زمینه برای شما بدون پاسخ بماند، جوابهای کوتاه اما مفیدی دادهایم که با استفاده از آن میتوانید به سوال خود پاسخ صحیحی را بدهید.
چرا باید از useState در ری اکت استفاده شود؟
برای مدیریت وضعیت داخلی کامپوننتها و ایجاد قابلیت واکنشپذیری در رابط کاربری استفاده میشود.
چرا مقدار state بلافاصله پس از setState تغییر نمی کند؟
زیرا بروزرسانیهای state در ری اکت بهصورت غیرهمزمان انجام میشوند و ممکن است برای بهینهسازی عملکرد با سایر بروزرسانیها ترکیب شوند.
چگونه می توان به مقدار قبلی state دسترسی داشت؟
با استفاده از فرم تابعی setState
که مقدار قبلی را به عنوان آرگومان دریافت میکند، مانند:
setState(prev => prev + 1)
آیا تغییر مستقیم state در ری اکت مجاز است؟
خیر، تغییر مستقیم state منجر به از دست رفتن قابلیت بروزرسانی رابط کاربری و ایجاد رفتارهای غیرمنتظره میشود.
در چه شرایطی استفاده از useState مناسب نیست؟
زمانی که مقدار مورد نظر را میتوان بهصورت مستقیم از props یا سایر دادههای موجود محاسبه کرد.
تفاوت استفاده از مقدار ثابت و فرم تابعی در setState چیست؟
فرم تابعی همواره از جدیدترین مقدار state استفاده میکند و برای بروزرسانیهای متوالی یا سریع، روش مطمئن تری محسوب میشود.
جمع بندی
استفاده درست از هوک useState
در ری اکت نقش مهمی در ساخت اپلیکیشنهای قابل اعتماد و بهینه دارد. با شناخت و پرهیز از اشتباهات رایجی مانند: نادیده گرفتن مقدار قبلی وضعیت، تغییر مستقیم state
، درک نادرست از بهروزرسانیهای غیرهمزمان و استفاده نادرست از state
برای دادههای قابل محاسبه، میتوان عملکرد کامپوننتها را قابل پیشبینیتر و راحتتر کرد. رعایت این نکات، مسیر توسعه ری اکت را حرفهای و کاربردیتر کرده است.
برای ادامه مطالعه و یادگیری: چگونه یک برنامه React را با استفاده از Nginx بر روی سرور مجازی Ubuntu نصب کنیم؟