Saeideh abs
Saeideh abs
خواندن ۷ دقیقه·۲ ماه پیش

سوالاتی که از من در مصاحبه‌های توسعه‌دهنده Frontend پرسیده شد (بخش ۳)

سلام و درود
در ادامه سری سوالات مصاحبه، این سری، سوالات مربوط به react رو بررسی میکنیم.
بخش اول که مربوط به سوالات جاوااسکریپت هست رو از این لینک میتونید بخونید.
بخش دوم که ترکیبی از سوالات عملی و live code جاوااسکریپت و الگوریتم و حل مسئله هست رو هم از این لینک میتونید بخونید.
اما بریم سراغ سوالات react


۱- پارامتر key در react که در لوپ ها ملزم به استفاده از اون هستیم، چی هست؟ و استفاده از ایندکس به عنوان key چه محدودیت هایی داره؟
لینک زیر اول به خوبی مفاهیم virtual dom و reconciliation رو توضیح داده و سپس نحوه استفاده از پارامتر key رو باز کرده: key parameter


۲- تفاوت React.Fragment و </>...<>
هر دو React.Fragment و <>...</> برای گروهبندی چندین المنت بدون اضافه کردن یک المنت والد اضافی به DOM استفاده می شن. اما React.Fragment می تونه attribute هایی مثل key که برای رندر کردن لیست ها مفید هست رو بپذیره در حالی که </>...<> نمی تونه این attribute ها رو بپذیره.


۳- توضیح دهید virtual dom چیست؟
پاسخ: virtual dom


۴- فرق useMemo و useCallback و کاربرد هر کدام را توضیح دهید. آیا همیشه از این ها باید استفاده کنیم(چه مواقعی باید از این هوک ها استفاده کنیم)؟
بهترین منبع برای اینجور مطالب داکیومنت خود react هست(که تو مثال های خودش به بخش دوم سوال هم پاسخ داده): useCallback & useMemo
اما از این لینک هم میتونید به صورت خلاصه و زبان فارسی تفاوت این دو هوک رو بخونید: useMemo vs useCallback


۵- توضیح دهید هوک useEffect چی هست و چه طور life cycle های کلاس کامپوننت ها رو پیاده میکنه؟
تعریف useEffect :useEffect
اما به روش های زیر میتونیم life cycleها رو با useEffect پیاده سازی کنیم:

componentDidMount

componentDidMount
componentDidMount


componentDidUpdate

componentDidUpdate_1
componentDidUpdate_1


اما اگر بخوایم اولین رندر رو skip کنیم میتونیم این شکلی بنویسیمش:

componentDidUpdate_2
componentDidUpdate_2


componentWillUnmount

componentWillUnmount
componentWillUnmount

۶- خروجی کدهای زیر رو با هم مقایسه کنید:

useEffect(() => { console.log('test') }) useEffect(() => { console.log('test') }, [ ]) useEffect(() => { console.log('test') }, [a]) useEffect(() => { return () => console.log('test') }, [ ])


در اولین useEffect از اونجایی که dependency array رو ندادیم بهش، پس console.log در هر بار رندر شدن کامپوننت(چه در رندر اولیه، چه در هر اپدیت) اجرا میشه.
دومین useEffect فقط در اولین رندر اجرا میشه.
سومین useEffect فقط زمانی اجرا میشود که مقدار a تغییر کنه.
در چهارمین useEffect, پیش از unmount شدن کامپوننت، console.log اجرا میشه.


۷- کد زیر چندبار اجرا میشود؟

const [state, setState] = useState({a:1}) useEffect(() => { setState({a:1}) }, [state])

کد بالا به صورت بی نهایت اجرا میشه و باعث ایجاد یک حلقه بی پایان میشه. علتش هم اینه که هربار که ما
setState({a:1}) رو کال میکنیم، از اونجایی که {a:1} یک آبجکت جدید رو برمیگردونه(هرچند محتوا یکسان هست اما رفرنسشون در حافظه متفاوته)، پس state هر بار در حال تغییر کردن هست و چون state جزو آرایه وابستگی useEffect هست پس useEffect مجددا اجرا میشه.


۸-کاربرد هوک useLayoutEffect چیست؟
از داکیومنت خود react میتونید درباره اش بخونید: useLayoutEffect


۹- آیا useEffect, سنکرون (sync) هست یا آسنکرون (async)؟

برخلاف useLayoutEffect که قبل ازینکه مرورگر اسکرین رو repaint بکنه به صورت سنکرون اجرا میشه، useEffect به صورت آسنکرون بعد از repaint شدن اسکرین توسط مرورگر اجرا میشه. به خاطر همین هم برای استفاده از useLayoutEffect باید دقت کنید که پردازشتون اگه خیلی سنگین باشه، میتونه رندرینگ UI رو بلاک کنه.


۱۰- کاربرد هوک useImperativeHandle چیست؟

پاسخ: useImperativeHandle


۱۱- هوک useReducer و کاربردهای اون رو توضیح دهید.

داکیومنت خود react برای useReducer: useReducer
از اینجا هم میتونید مقایسه useState و useReducer رو بخونید: useState vs useReducer

به طور مثال اما useRducer جایی کاربرد داره که مثلا شما اکشن های مختلفی رو قراره روی stateتون اعمال کنید. به طور مثال توی یک اپ counter، شما اکشن های مختلفی مثل increment, decrement, reset و ... رو ممکنه داشته باشید. تو همچین شرایطی به جای اینکه state رو با event handlerها اپدیت کنید، میتونید از useReducer استفاده کنید و تابع reducerتون رو اصلا به یک فایل دیگه خارج از کامپونتتون منتقل کنید. همچنین توی تابع reducer میتونید اکشن های reset, decrement, increment رو هندل کنید.
نقل قول از داکیومنت react:


useReducer is very similar to useState, but it lets you move the state update logic from event handlers into a single function outside of your component. Read more about choosing between useState and useReducer.

۱۲- خروجی کد زیر چیست؟

const myref = useRef(0); useEffect(() => { console.log(1); }, [myref.current]) ... <button ={() => myref.current += 1}>click</button>

اگر کد بالا رو اجرا کنید، میبینید که فقط یکبار عدد ۱ توی کنسول چاپ میشه (زمانی که کامپوننت mount میشه). بعد از اون هر چه قدر که دکمه click رو کلیک بکنید، هیچ چیزی توی کنسول چاپ نمیشه. علتش هم اینه که تابع داخل useEffect اصلا فایر نمیشه. حالا چرا فایر نمیشه؟ به خاطر اینکه اپدیت کردن ref (اینجا myref) باعث ریرندر شدن کامپوننت نمیشه. فقط زمانی کامپوننت ریرندر میشه که state ها اپدیت بشن. لذا چون ریرندری اتفاق نمیفته، پس useEffect هم هیچوقت مقدار myref.current فعلی رو با قبلی مقایسه نمیکنه که متوجه تغییری بشه (که اگر مقادیر موجود در dependency array تغییر کرده بود، تابع رو اجرا کنه).


۱۳- چند مورد از کاربردهای ref رو در react بگویید.

همونطور که تو سوال قبل هم اشاره شد، یه نکته مهم در رابطه با ref این هست که باعث رندر مجدد کامپوننت نمیشه. کاربردهاش هم مرتبط به همین ویژگیش هست:

  • دسترسی مستقیم به عناصر DOM
    با استفاده از ref میتونید مستقیما با عناصر HTML تعامل داشته باشید و ویژگی هایی مثل فوکوس، اسکرول و ... رو کنترل کنید.
  • ذخیره مقادیری که نیاز به رندر مجدد ندارن، اما میخواهیم اون مقادیر بین ریرندرها، حفظ بشن
    متغیرهای معمولی، در ریرندرها، مجدد initialize میشن، لذا نمیتونن مقدار قبلی رو حفظ کنن. از اون طرف state ها هم با اپدیت شدن، باعث رندر مجدد کامپوننت میشن. اگر نیاز به متغیری دارید که مقدارش بین ریرندرها حفظ بشه، اما اپدیت شدنش باعث ریرندر شدن کامپوننت نشه، از ref لازمه استفاده کنید.
  • دسترسی به کامپوننت های فرزند (forwarding refs)
    با استفاده از ref میتونید ویژگی هایی مثل فوکوس، کلیک و ... رو در کامپوننت فرزند کنترل کنید.
  • ارتباط با APIهای خارجی مثل API مرورگر
    برای کار کردن با APIهایی که تاثیری روی ظاهر کامپوننت شما ندارن، مثل ذخیره کردن timeout IDs یا سیگنال abort controller، میتونید از ref استفاده کنید.

۱۴- این امکان هست که useState برای set کردن initial value، یه function بگیره. کاربرد اون function چی هست؟

پاسخ: function in useState


۱۵- توضیح دهید state batching در react چیست؟

در ری اکت, به منظور افزایش performance, چندتا setState که داخل یک event handler یا متد lifecycle هستن, batch میشن و بلافاصله بعد یک setState ریرندرینگ اتفاق نمیفته, بلکه setState ها batch میشن و در آخر اون متد lifecycle یا event handler یک بار rerendering انجام میشه. در نتیجه با جلوگیری از ریرندرهای بیهوده, performance افزایش پیدا میکنه.


۱۶- توضیح دهید react fiber چیست؟

ری اکت فایبر, یک نسخه تجدید نظر شده از الگوریتم تطبیق(reconciler) ری اکت هست، که مسئول به روزرسانی virtual DOM و بازتاب دادن تغییراتش توی actual DOM هست. در react fiber یک سری internal optimizations انجام شد که هدف بهبود performance برنامه های ری اکتی و افزایش سرعت و هوشمندی ری اکت بود. ری اکت فایبر در نسخه 16 ری اکت به عموم معرفی شد که بعد از اون, فایبر, reconciler دیفالت ری اکت هست.


۱۷- فرض کن که یک لیست خیلی بزرگی از آیتم ها رو داریم و قراره رندر کنیم. چه طور این کار رو انجام میدی؟ آیا از تکنیک خاصی استفاده میکنی؟

بله، برای رندر کردن لیست های بزرگ میشه از تکنیک list virtualization استفاده کرد تا performance پایین نیاد. list virtualization تکنیکی هست که طی اون فقط آیتم هایی از لیست که در اسکرین visible هستن، رندر میشن و سایر آیتم هایی که قابل مشاهده نیستن، رندر نمیشن. این کار باعث میشه که performance به صورت قابل ملاحظه ای افزایش پیدا کنه (تو لیست های بزرگ). از لینک زیر میتونید بیشتر درباره list virtualization بخونید: list virtualization


۱۸- توضیح دهید jsx چیست و بعد از اجرا شدن به چه چیزی تبدیل میشود(HTML یا جاوااسکریپت)؟

از این لینک میتونید پاسخ بخش اول رو بخونید: jsx
اما پاسخ بخش دوم: jsx بعد از کامپایل شدن توسط ابزارهایی مثل babel,... تبدیل به جاوااسکریپت میشه. در واقع طی این تبدیل، jsx به React.createElement کال هایی تبدیل میشه که react ازشون برای ساخت virtual dom استفاده میکنه.
برای مثال، کد زیر:

تبدیل به این کد میشه:


۱۹- با توجه به اصول SOLID یک مثال از کاربرد اصل open/close در react بزنید.

توی این لینک به زیبایی درباره SOLID و اعمال کردن اصولش در برنامه های ری اکتی، همراه با مثال، صحبت شده: SOLID in react


خب، سوالات مصاحبه react هم تموم شد:) توی قسمت بعدی میریم سراغ server side rendering و nextjs!

منابع:

https://meganslo.medium.com/why-is-reacts-key-prop-important-b6bd51124270
https://ditty.ir
https://react.dev
https://virgool.io/@farnaz.khoshgoftar/usememo-vs-usecallback-d3mfcl8xa5bc
https://www.patterns.dev
https://blog.stackademic.com/react-native-masters-solid-principles-in-react-react-native-a1b8df8d261d



ری اکتreactfrontendinterviewمصاحبه
شاید از این پست‌ها خوشتان بیاید