آنچه در این مقاله میخوانید [پنهانسازی]
یکی از سوالهایی که بعد از کار با React برای خیلی از برنامه نویسها پیش میآید این است که چرا بعضی کامپوننتها دوبار اجرا یا Render میشوند. این موضوع مخصوصا بعد از React 18 بیشتر دیده شد و باعث شد خیلی از توسعه دهندهها فکر کنند پروژه مشکل دارد. در واقع، دوبار Render شدن React معمولا به خاطر Strict Mode، مدیریت اشتباه State یا استفاده نادرست از useEffect اتفاق میافتد و اگر دلیل آن را بدانید، کنترلش خیلی راحتتر میشود.
سرفصل های مقاله
- Render در React دقیقا چیست؟
- چرا React دوبار Render می شود؟
- فعال بودن React Strict Mode
- اجرای دوباره useEffect
- تغییر State داخل Render
- تغییر مداوم Props
- استفاده اشتباه از Context
- دوبار Render شدن React در React 18
- چه زمانی دوبار Render شدن طبیعی است؟
- چه زمانی دوبار Render شدن خطرناک است؟
- روش پیدا کردن دلیل Render اضافی
- استفاده از React DevTools
- استفاده از console.log
- بررسی useEffect ها
- روش حل دوبار Render شدن React
- استفاده درست از Dependency Array
- استفاده از useMemo
- استفاده از React.memo
- مدیریت درست Context
- حذف Strict Mode برای تست
- اشتباهات رایج برنامه نویسان React
- صدا زدن API داخل Render
- ساخت Function جدید در هر Render
- استفاده زیاد از Global State
- روش جلوگیری از Render اضافی در React
- کامپوننتها را کوچک نگه دارید
- State غیر ضروری نسازید
- از Profiler استفاده کنید
- جمع بندی
Render در React دقیقا چیست؟
هر بار که React رابط کاربری را به روز رسانی میکند، فرآیندی به نام Render اتفاق میافتد.
به زبان ساده:
- React دادهها را بررسی میکند
- تغییرات را تشخیص میدهد
- UI را دوباره محاسبه میکند
مثلا:
function App() {
return <h1>Hello React</h1>
}
هر بار که State یا Props تغییر کنند، React دوباره این کامپوننت را Render میکند.
چرا React دوبار Render می شود؟
دلایل مختلفی وجود دارد اما چند مورد از بقیه رایجتر هستند.
فعال بودن React Strict Mode
در React 18 وقتی Strict Mode فعال باشد، React بعضی کامپوننتها را عمدا دوبار اجرا میکند.
مثلا:
<React.StrictMode>
<App />
</React.StrictMode>
این رفتار برای پیدا کردن:
- Side Effect های خطرناک
- Memory Leak
- مشکلات Async
طراحی شده است.
خیلی از برنامه نویسها فکر میکنند پروژه خراب شده اما در واقع React دارد رفتار کد را بررسی میکند.
اجرای دوباره useEffect
یکی از رایجترین دلایل دوبار Render شدن React مربوط به useEffect است.
مثلا:
useEffect(() => {
fetchData()
})
در این حالت useEffect بعد از هر Render اجرا میشود.
چون Dependency Array تعریف نشده است.
روش درست:
useEffect(() => {
fetchData()
}, [])
حالا فقط یک بار اجرا میشود.
تغییر State داخل Render
این اشتباه خیلی خطرناک است:
function App() {
const [count, setCount] = useState(0)
setCount(count + 1)
return <div>{count}</div>
}
اینجا هر Render باعث تغییر State میشود و دوباره Render جدید اتفاق میافتد.
نتیجه:
- Loop بی نهایت
- مصرف شدید CPU
- کرش شدن صفحه
تغییر مداوم Props
اگر والد مدام داده جدید ارسال کند، فرزند هم دوباره Render میشود.
مثلا:
<Child data={{name: "Ali"}} />
در ظاهر مقدار ثابت است اما در هر Render یک Object جدید ساخته میشود.
React این را تغییر جدید در نظر می گیرد.
استفاده اشتباه از Context
بعضی پروژهها تمام State را داخل Context قرار میدهند.
نتیجه:
- با کوچکترین تغییر
- کل کامپوننتها دوباره Render میشوند
این موضوع در پروژههای بزرگ Performance را نابود میکند.
دوبار Render شدن React در React 18
بعد از React 18 خیلی از توسعه دهندهها متوجه این رفتار شدند.
مخصوصا در Development Mode.
مثلا Console دوبار لاگ میدهد:
console.log("render")
خروجی:
render
render
این موضوع معمولا به خاطر Strict Mode است و در Production اتفاق نمیافتد.
چه زمانی دوبار Render شدن طبیعی است؟
همیشه دوبار Render شدن مشکل نیست.
بعضی وقتها React برای:
- بهینه سازی
- بررسی تغییرات
- پیدا کردن Side Effect
این کار را انجام میدهد.
اگر:
- پروژه کند نشده
- Loop ایجاد نشده
- Memory Leak ندارید
معمولا جای نگرانی نیست.
چه زمانی دوبار Render شدن خطرناک است؟
وقتی:
- API چند بار صدا زده شود
- مصرف RAM بالا برود
- صفحه کند شود
- درخواست های تکراری ایجاد شوند
- کامپوننت ها بی دلیل اجرا شوند
باید مشکل را جدی بررسی کنید.
روش پیدا کردن دلیل Render اضافی
استفاده از React DevTools
یکی از بهترین ابزارها React DevTools است.
داخل بخش Profiler می توانید ببینید:
- کدام کامپوننت Render شده
- چند بار Render شده
- چه چیزی باعث Render شده
این ابزار برای Debug پروژههای بزرگ خیلی مهم است.
استفاده از console.log
مثلا:
console.log("Component Rendered")
اگر لاگ مدام تکرار شود یعنی Render اضافی دارید.
بررسی useEffect ها
بیشتر Loop ها از useEffect شروع میشوند.
مثلا این کد خطرناک است:
useEffect(() => {
setData(newData)
}, [data])
چون تغییر data دوباره useEffect را اجرا میکند.
روش حل دوبار Render شدن React
استفاده درست از Dependency Array
همیشه Dependency ها را دقیق تعریف کنید.
مثلا:
useEffect(() => {
fetchUsers()
}, [])
این باعث میشود Effect فقط یک بار اجرا شود.
استفاده از useMemo
اگر Object یا Array جدید میسازید:
const user = useMemo(() => {
return {name: "Ali"}
}, [])
این کار از Render اضافی جلوگیری میکند.
استفاده از React.memo
برای جلوگیری از Render غیر ضروری:
export default React.memo(Component)
این روش مخصوص کامپوننتهای سنگین خیلی مفید است.
مدیریت درست Context
نباید تمام State پروژه را داخل یک Context قرار دهید.
بهتر است:
- Context ها کوچک باشند
- State ها تفکیک شوند
- دادههای سنگین جدا مدیریت شوند
حذف Strict Mode برای تست
اگر می خواهید مطمئن شوید مشکل از Strict Mode است:
<App />
موقتا Strict Mode را حذف کنید.
اگر مشکل از بین رفت، یعنی React فقط رفتار پروژه را بررسی می کرده است.
البته در پروژه واقعی بهتر است Strict Mode را نگه دارید.
اشتباهات رایج برنامه نویسان React
صدا زدن API داخل Render
این اشتباه خیلی خطرناک است:
function App() {
fetch('/api/data')
return <div>Hello</div>
}
هر Render دوباره API را صدا میزند.
ساخت Function جدید در هر Render
مثلا:
<button onClick={() => handleClick()} />
در پروژههای بزرگ این موضوع باعث Render اضافی میشود.
گاهی بهتر است از useCallback استفاده شود.
استفاده زیاد از Global State
بعضی پروژهها همه چیز را داخل Redux یا Context ذخیره میکنند.
نتیجه:
- Render اضافه
- مصرف RAM بیشتر
- کند شدن UI
روش جلوگیری از Render اضافی در React
کامپوننتها را کوچک نگه دارید
کامپوننتهای بزرگ سخت تر کنترل میشوند.
هرچه Component کوچکتر باشد:
- Debug راحتتر است
- Render بهتر مدیریت میشود
- Performance بالاتر میرود
State غیر ضروری نسازید
هر State جدید یعنی احتمال Render بیشتر.
قبل از ساخت State از خودتان بپرسید:
- آیا واقعا لازم است؟
- آیا می شود Derived Data باشد؟
از Profiler استفاده کنید
خیلی از مشکلات Performance فقط با چشم دیده نمیشوند.
Profiler کمک میکند دقیقا بفهمید مشکل از کدام بخش پروژه است.
جمع بندی
دوبار Render شدن React همیشه به معنی خراب بودن پروژه نیست. در خیلی از مواقع React برای بررسی Side Effect ها و پیدا کردن مشکلات احتمالی این کار را انجام میدهد. اما اگر Render اضافی باعث کندی پروژه، درخواستهای تکراری یا مصرف زیاد منابع شود، باید ساختار State، useEffect و Context ها را دقیق بررسی کنید. بیشتر مشکلات با مدیریت درست Dependency ها و بهینه سازی کامپوننتها قابل حل هستند.






