آشنایی با تغییرات React 17؛ بهروزرسانی بدون افزوده شدن قابلیت جدید
۲۶ مرداد ۱۳۹۹
دو سال و نیم است که از انتشار اولین نسخه React ۱۶ میگذرد. تیم توسعه React وعده داده که نسخه ۱۷ برای آینده بسیار مهم است، اما ادعاها حاکی از این است که در نسخه جدید، ویژگی جدیدی اضافه نشده است! اینها به چه معنی هستند؟ چگونه میتوانند بدون افزودن ویژگیهای جدید به React، نسخه جدیدی از آن را انتشار دهند؟
بهروزرسانیهای تدریجی در React
بهروزرسانیهای گذشته، همیشه باعث منسوخ شدن ورژنهای قدیمیتر این فریمورک میشد. این موضوع، تیمها را در مسیر upgrade کردن پروژهشان به نسخه جدید React، بسیار اذیت میکرد. مخصوصا اگر حجم کدهای پایه پروژه زیاد باشد، دشواریها دوچندان میشدند. بنابراین تیم توسعه این فریمورک تصمیم گرفته است که روش جدیدی در بهروزرسانیهای خود اتخاذ کند. زمانی که نسخه 18 این فریمورک انتشار پیدا کند، توسعهدهندگان قادر به انتخاب هستند که فقط بخشهایی از برنامه خود را ارتقا دهند و سایر قسمتهای برنامه بر روی React نسخه ۱۷، کار خودشان را ادامه خواهند داد.
این قابلیت، به تیمهای توسعهای که مداوما نمیتوانند برنامه خود را نگهداری کنند یا نیازی به انتقال برنامهشان برروی نسخههای جدید ندارند، کمک میکند. اما این تصمیم برخلاف تیمهایی است که همیشه در حال نگهداری و توسعه پروژهشان هستند. در نسخههای جدیدتر React، سازگاریهای برنامهها با نسخههای قبل حفظ میشود و دیگر نیاز نیست قسمتهای زیادی از برنامهتان را به نسخه جدیدتر، انتقال دهید.
برای محقق کردن این قابلیت، تیم توسعه React مدت زمانی را برای اصلاح سیستم رویداد (event-system) صرف کرده و این بهروزرسانیها چیزی است که باعث شده نسخه جدید React، بهعنوان یک بهروزرسانی اصلی تلقی شود، زیرا میتواند در عملکرد تمام برنامههای قدیمی، اختلال ایجاد کند.
تغییر در Event Delegation
برخلاف تصور، رویدادها در React به المنت خاصی پیوست نمیشدند. درعوض فریمورک React یک handler را برای هر نوع رویداد به Document
متصل میکرده است. این روش باعث افزایش کارایی در برنامههای کاربردی با المنتهای بسیار تودرتو، میشد. همچنین قابلیتهایی مانند replaying events را نیز فراهم میآورد.
در پسزمینه React، میتوان یک رویداد را Capture (پیمایش المنتها از بالا به پایین، شناسایی و اجرای المنتهایی که با اولویت بالایی درخواست شده باشند) و تعیین کرد تا کدام کامپوننت، قبل از شروع پیمایش برای پیدا کردن رویداد دیگری که در ساختار درختی کامپوننتها قرار دارد، صدا زده شود.
بااینحال، در کدهایی که از جاوااسکریپت خام استفاده میشود، رویدادها از سطح Document
شروع به پیمایش میشوند. ممکن است این اتفاق را یک مشکل تلقی نکنیم، اما در اجرای چند نمونه از React باعث بروز مشکل میشود. اگر برنامهای که با React نوشتهاید، در برنامه دیگری با همین فریمورک قرار بگیرد، باعث میشود پیمایش و شناسایی رویدادها، متوقف شود و برنامه React والد، به Capture کردن رویدادها ادامه دهد. این یک مشکل بزرگ برای توسعهدهندگانی بود که میخواستند از ورژنهای مختلف React، درون یکدیگر استفاده کنند. شاید فکر کنید که در تولید یک محصول، این اتفاق نمیافتد اما ویرایشگر کد Atom، چهار سال پیش با این مشکل روبرو شد.
در نسخه جدید React، کنترل کنندههای رویداد به المنت ریشه (root) برنامه ما پیوست میشوند. این موضوع باعث میشود که عملیات Nesting در ساختار درختی React، ایمنتر انجام شود. برای استفاده از این قابلیتها، باید از نسخه ۱۷ یا بالاتر React استفاده کنید. این قابلیتهای جدید در بهروزرسانی اخیر باعث میشود که راحتتر از React و کتابخانهای مانند JQuery، درون یکدیگر استفاده کنیم.
بهینهسازی effect cleanup
useEffect(() => {
// This is the effect itself.
return () => {
// This is its cleanup.
};
});
متدوال است که درuseEffect
، با return کردن یک تابع (function)، اجرای دیگر کدهای درون این تابع را متوقف کنیم. این تابع در گذشته بهصورت همزمان (Synchronously) قبل از ترسیم فریم بعدی اجرا میشد. در واقع، بیشتر برنامهها با استفاده از روشهای cleanup موجود دیگر نیازی به تاخیر برای بهروزرسانی صفحه ندارند. اما تابعای که امروزه return میشود، بهصورت غیرهمزمان (Asynchronously)، قبل از اینکه React فریم بعدی را رندر کند، اجرا میشود. این اتفاق باعث میشود که زمانِ سویچ کردن بین کامپوننتهای مختلف کمتر شده و اجرای سریعتری را شاهد باشیم. هنوز هم میتوانید از روش useLayoutEffect
بهعنوان روش cleanup برای مسدود کردن حلقه رندر (render loop) استفاده کنید.
حذف Event pooling
کد زیر در React نسخه ۱۶، باعث متوقف شدن برنامه میشود.
function handleChange(e) {
setData(data => ({
...data,
// This crashes in React 16 and earlier:
text: e.target.value
}));
}
Event pooling بسیار گیج کننده است و هیچگونه بهینهسازی در مرورگرهای مدرن ارائه نمیدهد. درعوض، میتواند باعث بروز باگهایی در هنگام دریافت یک رویداد یکسان در چندین کامپوننت شود. ممکن است یک کنترل کننده رویداد، رویدادی را برابر با null قرار دهد و کامپوننتهای دیگری که از این رویداد استفاده میکنند، با خطا روبرو میشوند. بهصورت خلاصه میتوان گفت که در نسخه جدید React، زمانی که به فیلدهای رویدادی نیاز داشته باشید، میتوانید به آنها دسترسی پیدا کنید.
اینگونه نبود که در نسخه ۱۷ فریمورک React، قابلیتهای جدیدی اضافه شود. درعوض، تیم توسعه React یک ذهنیت جدید را خلق کرده است. شاید در حال حاضر، بهروزرسانی که در آن کامپوننتها یا hookهای جدید توسعه یافته باشند را در اختیار نداشته باشیم، اما این تغییر روند کلی React باعث پیشرفتهای بزرگی در آینده این فریمورک میشود. شما با اجرای دستور:
npm install react@17.0.0-rc.0 react-dom@17.0.0-rc.0
میتوانید نسخه ۱۷ این فریمورک را در پروژههای خود امتحان کنید.