useEffect در مقابل useLayoutEffect

۱۴۰۳/۱۱/۲۲
useeffect-uselayouteffect

این مقاله، ترجمه‌ای است از مقاله‌ی اصلی به نام useEffect vs useLayoutEffect که توسط Kent C. Dodds نوشته شده است.

اساسا از هر دو این موارد می‌توان برای یک کار مشابه استفاده کرد، اما موارد استفاده آن‌ها کمی با هم تفاوت دارند. بنابراین اینجا به قوانینی می‌پردازیم که بتوانیم تصمیم بگیریم از کدام هوک React استفاده کنیم.

useEffect

۹۹ درصد مواقع این همون چیزی هست که باید استفاده کنید. از زمانی که هوک‌ها جا افتادن و stable شدن و احیانا شما هم وقتی خواستید class componentهای خودتون رو با هوک‌ها بازنویسی کنید، احتمالاً کدهای مربوط به componentDidMount، componentDidUpdate و componentWillUnmount رو به useEffect منتقل کردید.

نکته‌ای که وجود داره اینه که این هوک بعد از رندر شدن کامپوننت توسط React اجرا می‌شه و اطمینان می‌ده که کالبک effect باعث مسدود شدن رندر مرورگر نمی‌شه. این رفتار با class componentها متفاوت هست، چون در اون‌ها componentDidMount و componentDidUpdate به صورت همزمان بعد از رندر اجرا می‌شن. این روش کارایی بهتری داره و در اکثر مواقع چیزی هست که می‌خواید.

با این حال، اگر افکت شما (از طریق یک ref) تغییری در DOM ایجاد کند و این تغییرات باعث شود ظاهر گره (node) DOM بین زمان رندر و اجرای افکت تغییر کند، در این صورت نباید از useEffect استفاده کنید. در این شرایط باید از useLayoutEffect استفاده کنید. در غیر این صورت، کاربر ممکن است یک فلیکر (تغییر ناگهانی ظاهر) را هنگام اعمال تغییرات DOM مشاهده کند. میشه گفت این تقریباً تنها زمانی هست که باید از useEffect اجتناب کنید و به جای آن از useLayoutEffect استفاده کنید.

useLayoutEffect

این هوک به صورت همزمان و بلافاصله پس از انجام تمام تغییرات DOM توسط React اجرا می‌شود. این ویژگی می‌تواند زمانی مفید باشد که نیاز دارید اندازه‌گیری‌هایی از DOM (مانند گرفتن موقعیت اسکرول یا استایل‌های دیگر برای یک المنت) انجام دهید و سپس تغییرات DOM را اعمال کرده یا با بروزرسانی state، رندر همزمان مجدد ایجاد کنید.

از نظر زمان‌بندی، این عملکرد مشابه componentDidMount و componentDidUpdate است. کد شما بلافاصله پس از بروزرسانی DOM اجرا می‌شود، اما قبل از این که مرورگر فرصت داشته باشد تا تغییرات را "رندر" (paint) کند (کاربر تغییرات را تا زمانی که مرورگر آن‌ها را دوباره رندر نکرده باشد، نمی‌بیند).

خلاصه

  • useLayoutEffect: اگر نیاز دارید که DOM را تغییر دهید و/یا اندازه‌گیری‌هایی انجام دهید.
  • useEffect: اگر نیازی به تعامل با DOM ندارید یا تغییرات DOM شما قابل مشاهده نیستند (در واقع، بیشتر مواقع باید از این استفاده کنید).

یک مورد خاص

یک موقعیت دیگر که ممکن است لازم باشد از useLayoutEffect به جای useEffect استفاده کنید زمانی است که در حال بروزرسانی یک مقدار (مانند یک ref) هستید و می‌خواهید اطمینان حاصل کنید که قبل از اجرای هر کد دیگری، مقدار به‌روز شده است. برای مثال:

const ref = React.useRef()
React.useEffect(() => {
	ref.current = 'some value'
})

// then, later in another hook or something
React.useLayoutEffect(() => {
	console.log(ref.current) // <-- this logs an old value because this runs first!
})

پس در چنین موقعیت‌هایی، راه‌حل استفاده از useLayoutEffect است.

نتیجه‌گیری

موضوع اصلی در مورد پیش‌فرض‌ها است. رفتار پیش‌فرض این است که به مرورگر اجازه داده می‌شود قبل از اجرای کد شما توسط React، بر اساس به‌روزرسانی‌های DOM دوباره رندر کند. این بدین معناست که کد شما مانع عملکرد مرورگر نمی‌شود و کاربر تغییرات DOM را سریع‌تر مشاهده می‌کند. بنابراین، در بیشتر مواقع بهتر است از useEffect استفاده کنید.

دسته‌بندی‌ها:

© 2024. تمامی حقوق محفوظ است