سلام و درود
در ادامه سری سوالات مصاحبه، این سری، سوالات مربوط به 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
componentDidUpdate
اما اگر بخوایم اولین رندر رو skip کنیم میتونیم این شکلی بنویسیمش:
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 touseState
, but it lets you move the state update logic from event handlers into a single function outside of your component. Read more about choosing betweenuseState
anduseReducer
.
۱۲- خروجی کد زیر چیست؟
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 این هست که باعث رندر مجدد کامپوننت نمیشه. کاربردهاش هم مرتبط به همین ویژگیش هست:
۱۴- این امکان هست که 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