Дваццаць запітанняў для інтэрв’ю React, які адзначаюць разліку межы вжывання і розумэння
Вярчыны DOM, ключы, эфекты, мемаізацыя, Кантэкст, SSR і гідратацыя — адказанае пра проблемы, якія на самай справе выявляюць адзінавальнікі, а не пра стандартныя вакласовыя апісанні.
Крыніцы: 20 React Interview Questions That Actually Trip People Up (And How to Nail Them)
Розробка на React і пояснэнне прынцыпаў React — гэта разныя навыкі. У адборах спрашваюць пра другі навык: што адбываецца пад час вызвання setState, чаму важлівы ключы, калі перзапускаюцца эфекты. Ніжэйшыя дваццаць запітання часта з’являюцца. Адпаведзі спрываюцься на проблемы, якія рашае кожны функцыянал, і на непрыемныя сітуацыі, якія выступаюць у працэйнай асяроддзі — а не на заучаныя тэксты.
1. Чаму ўсё-такі існуе Вярчыны ДОМ
Вярчыны ДОМ не ўжо чародзейскі порошак для прыяўлення скорасці. Гэта звычны дрэва JavaScript, якое опісвае, як павінна выглядаць інтэрфейсная частка. Калі змянюецца стан, React стварае новае вярчыны дрэва, порывнюе яго з пярэднім і супрацоўвае, прыкладаючы да рэальнага ДОМ браузера толькі неабходныя змены. Работа з рэальным ДОМ спрычыняе перзапіс паведамленняў і адрасаванне элементаў; мутацыі об’ектаў JavaScript коштаюць мало, таму React вікорыстоўвае рэсурсы CPU ў памяці, каб зашчадзіць рэсурсы браузера. Такі падход спрамованы на мінімізацыю навантажэння на браузер, а не на тое, каб кожна параджка была безкоштовная. Заява «Вярчыны ДОМ завжды быстрэйшы» без гэтай нюансаў — частая памылка начальных распрацоўшчыкаў.
2. Вярчыны ДОМ проты ДОМ браузера
Рэальныя апдэты DOM ўскладнены і можу спрычыняць перэраспалоўку і перамальёванне элементаў. Вярчынныя апдэты — гэта разлікі об’ектаў у памяці; React групавае дорогі запісы ў DOM замест таго, каб выконваць іх па разу за кожны вызов функцыі стану. Рэдагаванне за дапамогою track-changes лепшая, чым перапісванне всіго документа за кожную памылку.
3. Чаму ключы ліста важлівыя, калі радкі перамешчаюцца
Ключы ідэнтыфікуюць элементы праз усе перрэнды. Без іх React выкарыстоўвае позіцыю індэкса, што ламаецца, калі элементы дадаюцца, выкарыстоўваюцца або пераранжуюцца. Выкарыстоўванне індэкса масіва як ключа “функцыонуе” пакуль пераранжаванне не прыводзіць да таго, што полья і прабламы залішаюцца пры неправільных радках — гэта фальшывы “утэк стану”, які на самай працоўцы ёсць багам з ключамі. Лепш выкарыстоўваць стабільныя, унікальныя ID з дадзеных; індэксы паслужыць толькі для сапраўдна статычных лістоў. Калі продукт падтрымляе пераранжаванне за дапамогою ператасквання або фільтрацыю, індэксы як ключы зрэшты спакалююць локальны стан радкаў.
4. Паспяшнае раз’ясненне useState на адных прыняцых прынцыпах
Звычныя элементы інтэрфейсу гінуць, калі функцыя вяртаеся. useState дае функцыйнаму компоненту стойкую памяць і запланаваў перыскаляванне, калі гэтая памяць змінюецца:
const [count, setCount] = useState(0);
count — гэта тэкушчая значэнне; setCount запрашвае апдэйт. Апдэйт не прыкладываецца падчас самага перыскалявання: логаванне count адразу пасля setCount все равно паказвае пярэднюе значэнне, таму што новая цінная дань з’являецца толькі пад час наступнага перыскалявання.
5. Чаму абнаўленні useState здаюцца затрымленымі або групаванымі
React групавае абнаўленні, якія падаюць у одну і тую ж подыю, ў адна перыскаляванне. Зачынення React 18 гэтае групаванне распрастраняецца таксама на праграмы-обявы і таймеры, а не толькі на працоўнікі подый React. Калі вам патрэбна найновейшая цінная дань на адной з пярэдніх станоў, выкорыстаюце функцыйны апдэйтар:
setCount(prev => prev + 1);
Этот фармат чытае найсвежэйшую значэнне з лісты, а не застарэлы фотакап скарынкі. Адзінавальнікі часта запытваюць, што будзе, якшо вы скрыёце count унутрь таймауту без фармату апдэйта.
6. Какую проблему на самай справе рашыяе useEffect?
Рэндараванне павінна быць чыстай функцыяй з пропсаў і статау ў JSX. Аплікацыі таксама запрашоўваюць дадзеныя, прыкладзаюць аслухальнікі змаганняў, плануюць таймеры і вплываюць на DOM — гэта пабочныя эфекты. useEffect выкананае гэтае нечыстая праца пасля адкладання, а не падчас рэндаравання:
useEffect(() => {
const id = setInterval(() => console.log("tick"), 1000);
return () => clearInterval(id); // cleanup
}, []);
Функцыя чысткі, якая вяртаецца, выкананае раней за наступны эфект і пад час зняцья. Якшо яго праігнораваць, адзінавальнікі запытваюць пра дублікаты таймероў і аслухальнікаў, якія продовжаюць працаваць пасля зняцья.
7. Чым на самай справе керуе массів залежнасцяў?
Ён паведамляе React, калі трэба зноў выканаць эфект, праз паверхневыя порэвання:
[]— адзін раз пасля маунтаў[count]— знову, калі змянюеццаcount- не выканана — пасля кожнага рэндару (рэдкасцю бывае патрабавана)
Калі забыць значэнне, якое апісанае ў масе, то будзе створвацца старэе закрыцце: такі стан заставае першае зафіксаванае значэнне назаўсёды. Існуюць правіла праблэм-дэтэктавання, якія пераглядаюць усе залежнасці, таму што такія багі ўзнікаюць дужа часта.
8. Контролюваныя vs неконтролюваныя компоненты
Контролюваныя элементы вучаць value з стану React і апдэйтуецца праз onChange; правда належыць React.
Неконтролюваныя элементы зберагаюць стан DOM; яго чытаюць праз ref, калі гэта неабходна (часта пад адправкай даных).
// Controlled
<input value={name} onChange={e => setName(e.target.value)} />
// Uncontrolled
<input ref={inputRef} defaultValue="Dev" />
Рэжым кантролюеўання увімкчва рэальную перакантроль і фарматаванне за цену перыядзічнага атрыбутавання кожнай клавішы. Рэжым без кантролюеўання залічваецца легкім, калі патрэбна толькі фінальная значэнне. Магчымыя змешаныя формы — дзеякія польні кантролююцца, а дзеякія — ні — але ў аналізе ўскладненыя.
9. Перадача пропаў і калі зупыніцца
Перадача пропаў перадае даны праз шары, якія іх толькі перадаюць далей. Перэменаванне называе багато файлаў. Кантэкст дапамагае па тэме, аутантыкацыі чы рэгіону; Redux чы Zustand дапамагаюць, калі графікі стану становяцца складнымі. Нюанс: кантэкст не ўжо безкоштовны — кожны спожывач перыядзічна атрыбутуецца, калі значэнне зміняецца — таму ён не являецца стандартам для кожнага спільнага польна. Перадача пропаў на два роўні часта ёсць яснейшая, чым стварэнне прадаўця кантэксту для едынаковага значэння.
10. Калі лепшая вжыць useReducer замест useState?
Выбірайце useReducer, калі апдэты ведуцца за тыпам дзеяння, наступны стан залежыць ад паказванага стану спосабамі, якія не ўпростлены, або колькасць полей змінюецца разам:
function reducer(state, action) {
switch (action.type) {
case "increment": return { count: state.count + 1 };
case "reset": return { count: 0 };
default: return state;
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });
Гэта сваерадкая версія Redux унутрь компонента. Булевы параметры керуюцца за дапамою useState; складная логіка пераходу павінна знаходзіцца ў адным тэстуемым рэдзюсеры. Вынесенне гэтай логікі з апрацоўшчыкаў запуску ў JSX таксама робіць тэсты на елементы простымі, без неабходнасці атрыбутавання всей структуры.
11. Паспяшыце useMemo vs useCallback, не проста цытуючы документацыю
Оба функцыі ухіляюцца ад зайвых вычысленняў между пераадрасаваннямі для разных форм даных:
useMemoзберагае ў кэшы вырачаную значэннеuseCallbackзберагае ў кэшы адказ на функцію
const sorted = useMemo(() => expensiveSort(list), [list]);
const handleClick = useCallback(() => doThing(id), [id]);
Ідэнтычнасць функцыі мае значэнне, таму што кожная перрадарбаванне стварае новы об’ект функцыі. Перадача новай функцыі ў дзецкі элемент memo усувае можлівасць мемаўзавання; useCallback захоўвае стабільнасць канкранта. Не трэба вжываць гэтыя хукі ў всіх месцах — мемаўзаванне мае свою цэну. Яго трэба вікорыстоўваць толькі для складных або дорогіх операцый чы для мемаўзавання дзецкіх элементаў. Нерэшаннае мемаўзаванне — частая прычына памылак у начаткавіках, яку спецыялісты любя выявляць пад час адбору.
12. React.memo ўжытковы — але лёгка ўсунуць
React.memo прыменшае колькісць перрадарбавання, калі пропсы ёсць паверхнева ідэнтычныя. Новыя літэралы об’ектаў чы масоў зарачунваюцца як разныя, нават калі ў іх ідэнтычны змест, таму вікорыстанне { style: { color: 'red' } } робіць memo беспрактычным, калі толькі родзіцы не стабілізуюць пропсы за дапамогою useMemo/useCallback. У іншым случае memo толькі збільшуе вітраты на порэванне, не запобiegаючы выконанню задач дзецкім элементам.
13. Ключы як ідэнтыфікатор, а не проста паведамленне ў консолі
Ключы ёсць сістэмай ідэнтыфікацыі у React межы перзапускамі компонентов. Некарэктныя ключы выкарыстоўваюць неправільны элемент DOM для некорэктных дадзеных: стан формы застаецца ў іншай строце, анімазіі запускаюцца на неправільным элеменце, а useState у елементах ліста заставляе выкарыстоўваць значэння пярэднего элемента. Гэта выглядае як паспаленне стану; на самай працы гэта баг з ключамі. Дэманстрацыя несправнага ліста з ключамі-індэксамі ў сандбоксе — адна з найшырэйшых способаў запам’ятаваць гэта правіла.
14. Кантэкст: правыя і неправыя задачы
Кантэкст дзеляеся значэннямі, якія патрэбны многім компонентам, без неабходнасці перэдачы ўсіх параметраў — автаналізаванный корыстнік, тэма, локацыя:
const ThemeContext = createContext();
<ThemeContext.Provider value={theme}>
<App />
</ThemeContext.Provider>
Гэта падходзіць слаба для высакачастых станоў (значэнняя формы на кожны натыск клавішы) у вялікай структуры, таму што кожны корыстнік апдэйтуецца пасля кожных змян без выбірчай падпіскі. Лепшая выбраць хранэнне з болей тонкімі падпіскамі для такага фармата. Пераключэння тэм — класычны прыклад хорашага падходжання да кантэксту; адносны положэнні курсора ў спільным рэдактары зазвычай такога падходжання не маюць.
15. Спраўленне жыцёвых цыклаў класаў з эфектамі
Прыбліжнае спраўленне класаў:
componentDidMount→useEffect(..., [])componentDidUpdate→useEffect(..., [dep])componentWillUnmount→ чыстка эфектаў
Глыбэйшая змяненасць: ціклы жыцця працуюць па прынцыпу часу (з’яўленне/ацыі/знікненне); эфекты — па прынцыпе сінхронізацыі — трэба падтрымваць гармонію з гэтымі значэннямі, таму эфекты перзапускаюцца, калі змянююцыся залежнасці. Калі эфекты спрыяваюцца як методы ціклу жыцця, перакладзеныя лінія за лініёй, люды пачынаюць страждаць ад проблем з масавым спіскам залежнасцяў.
16. Стан у пораўнанні з пропамі
Пропы — гэта толькі чытальныя даны з бацькага компонента. Стан — гэта даны, якія належачы компоненту і выклікаюць павтарную нарадку, калі яны змянююцца. Пропы налаштовуюць компонент ззаўні; стан — гэта тое, што компонент памятае пра сабе. label кнопкі ёсць пропам; тое, чы робіцца яна недзейным падчас віканання запіту, — гэта стан. Плутанне гэтых двух праграмаў ведае да анты-патэранаў, такіх як спробы змяніць пропы або падняць тымчасовыя флагі UI занадта высока.
17. Аднаходжэнне непатрэбных павтарных нарадакоў без здагадкаў
Звычныя прычыны: адзінкі, які перадаюць новыя літэралы об’екта/масівы/функцыі, перарэндэраванне ўсіх корыстувачаў пад час змены кантэксту, або тое, што стан знаходзіцца на вышэйшай паверсі, чым трэба. Не спадзяйцеся — выкорыстоўваючы інструмент Profiler у React DevTools, запісайце адно з взаімадзейнаўанняў і паглядзеце, якія пропы зменіліся. Часта для вырашэння проблемы стан пераводзяць ніжча або дзеляюць компоненты, каб дорогія паддрэсі не адбываліся праз дэшавыя абнаўленні, а не спачатку накрыць усё useMemo. Інструменты профілювання ператвараюць вясковасць «здаецца, што ўсё медленна» на конкрэтныя пояснення ўзгаліва/пропаў, якія можна вырашыць.
18. SSR у порэвананні з CSR
CSR адрасуе тонкі HTML-шэлак плюс код на JS; прыстрой для перагляду стварае сторанку пасля завантажэння — шырока адпаведна, але памедзе ў стварэнні рэальнае версія сторанкі, історычна слабейша з точка зору SEO пакуль не запрацюе JS. SSR адрасуе HTML за кожны запіт, а пасля гідратацыя — праз прыўязку слухачаў; гэта дае лепшыя показнікі першага адрасавання сторанкі і SEO, але выклікае большую навантажэнна на сервер. Next.js і падобныя фрэймворкі дадаюць можлівасць статычнага генеравання і стрымінгу, але основны компроміс застаецца межу TTFB/SEO і вартасцю ўтратаў сервера ўсьведамлення. Заява «SSR завжды лепш» без указвання гэтага компроміса ёсцца слабым адказам у інтэрв’ю.
19. Несувяранасці гідратацыі і прычыны ўсунення іх
Функцыя Hydration прыўязвае React да HTML сервера, не выкарыстоўваючы маркап для збрасці. Несувямства выступаюць, калі HTML сервера не збігаецца з першым атрыбутаваннем на кліянце: Date.now() або Math.random() у працэсе атрыбутавання, перагляд window, які разніцяўся на серверэ, або дадатковыя элементы, якія вставляюцца. React сільна паветарае і часта ператрыбутаввае на кліянце, каб восстановіць стан — гэта додатковая праца плюс відны момент з некорэктным кантэнтам. Звычайны спосаб прыменшэння гэтых проблем — захаванне API, якія дзейнаць толькі ў браузеры, за дапамою useEffect або спецыяльных компонентаў.
20. Чаму React абгортае натыўныя з’явы ў SyntheticEvent
У React клас SyntheticEvent нормалізуе особлівасці розных прыгравароў (чаму onChange працуюць адносова аднакава), і ранейшыя версіі вікорыстоўвалі дэлегаванне адбуваюцца на роўні корня, замест аднае натыўная прыемнік на кожны вузел. У React 17+ дэлегаванне адбываецца на кантэйнер корня прыкладнення, а не на document, але ідэя застаўся тая ж. Ранейшы метод пулінга вікорыстоўвался для перадзяйснення аб’ектаў змагання, ўнаследкі чыго асінхронны доступ могаў вернуць null; пулінг зняты з версій React 17, але ведаць пра шар межу змагання прыгравара і прыемніка все ўсё паказвае глęбіну структуры. Адзначэнне таго, што e.nativeEvent все ўсё існуе пад спаднім шаром, паказвае, што вы розумееце, што абстракцыя ёсць толькі обгорткай, а не заменой для модэлю змагання DOM.
Што на самай працоўскай спышцы дзеясно ценіцца
Хорашыя адказы на запытаннія паводле якога ўскладнення, прычыны гэтага і як вы моглі б дапамогчы колеге — а не проста запам’ятаваная вялічына. Запытальнікі менш заўсёды заінтэрэсаваныя ў тым, чы можаце вы дастаць вялічыну useEffect, а больш — у тым, чы не сталіся у вас проблемы з застарэлымі клоузарамі, відсутнасцю чысткі або памылкамі ў залежнасцях, і чы можаце вы поясніць прычыны. Перад запытаннем перадаце гэтыя багі ў сандбоксе; доказы рэальных проблем паказваюць ваша разуменне. Вялічыны дапамагают перазйсці першую хвіліну; адносы выгод і історыі неудач прыводзяць да продажнага размовы.
Зберагачыце короткі персональны справак з працэвыканых вамі багоў — застарэлыя эфекты, некарэктныя клавішы, несувараснасці ў гідратацыі — і практыкуйцеся адказваць на запытанні пра кожны з іх за менш чаму за мінуту. Такая падготовка лепшая, чым запамятаванне сінтаксу API за ночь, і яна дапамагае даваць конкрэтныя прыклады, калі спакавальнік просіць практычны прыклад з вашай працы. Супаўнавайце кожны прыклад з адпаведным рашэнням, каб адказ заканчваўся ацэнкай, а не толькі опісам проблемы. Саме гэты крок адразняе тых, хто проста «чытае дакументацыю», ад тых, хто можа кераваць цім стэкам пад тыччую натоўпу.