React и Redux
Основы React — компоненты, хуки, состояние и эффекты, жизненный цикл, рендеринг, управляемые поля и ключи.
15 вопросов
JuniorТеорияОчень частоВ чём разница между управляемыми и неуправляемыми полями ввода в React?
В чём разница между управляемыми и неуправляемыми полями ввода в React?
У управляемого поля значение задаётся state React через prop value и обработчик onChange — state единственный источник истины, а DOM лишь отражает его. Неуправляемое поле держит значение в DOM без prop value; читают его через ref.
Типичные ошибки
- ✗Задавать
valueбезonChange, делая поле доступным только для чтения и замороженным - ✗Смешивать
valueиdefaultValueна одном поле - ✗Тянуться к
refдля чтения управляемого поля вместо чтения state
Уточняющие вопросы
- →Почему prop
valueбезonChangeделает поле доступным только для чтения? - →Когда неуправляемое поле с
ref— лучший выбор?
JuniorТеорияОчень частоЧто делают основные хуки React — useState, useEffect и useContext?
Что делают основные хуки React — useState, useEffect и useContext?
useState добавляет локальный state в функциональный компонент, возвращая текущее значение и сеттер, который перерендеривает при изменении. useEffect запускает побочные эффекты (подписки, запросы, работу с DOM) после рендера, а массив зависимостей управляет повторным запуском плюс необязательная очистка. useContext читает значение ближайшего провайдера для данного контекста, перерендеривая при его изменении.
Типичные ошибки
- ✗Вызывать хуки условно или в циклах, ломая отслеживание порядка вызовов в React
- ✗Опускать массив зависимостей
useEffect, из-за чего он выполняется после каждого рендера - ✗Мутировать state на месте вместо передачи нового значения в сеттер
Уточняющие вопросы
- →Почему хуки должны вызываться в одном порядке при каждом рендере?
- →Когда выполняется функция очистки
useEffect?
JuniorТеорияОчень частоВ UI-библиотеке React чем props отличаются от state?
В UI-библиотеке React чем props отличаются от state?
Props — это входные данные, переданные сверху от родителя; внутри получающего компонента они доступны только для чтения, и он не должен их мутировать. State — данные, которыми компонент владеет и управляет сам; их обновление (через setState или сеттер useState) планирует перерендер. Props текут в одну сторону (от родителя к ребёнку), state локален. Изменение любого из них вызывает перерендер компонента.
Типичные ошибки
- ✗Мутировать props напрямую вместо обращения с ними как с read-only входами
- ✗Хранить в state значение, полностью производное от props, что ведёт к рассинхрону
- ✗Думать, что ребёнок может протолкнуть изменения вверх, переприсвоив prop
Уточняющие вопросы
- →Как дочерний компонент сообщает родителю об изменении?
- →Когда производные данные должны жить в state, а когда вычисляться при рендере?
JuniorТеорияЧастоКроме списков, как смена key в React сбрасывает state компонента?
Кроме списков, как смена key в React сбрасывает state компонента?
key — это идентичность, по которой React решает, тот ли это инстанс между двумя рендерами. Если key прежний, React обновляет существующий инстанс и сохраняет его state; если key сменился, React размонтирует старый инстанс и монтирует новый, отбрасывая его state.
Типичные ошибки
- ✗Думать, что key важен только внутри списков и нигде больше
- ✗Ожидать, что смена key сохранит state, а не перемонтирует компонент
- ✗Считать, что key хранит или восстанавливает снимки state
Уточняющие вопросы
- →Когда привязка одиночного компонента по id записи — чистый паттерн сброса?
- →В чём разница между обновлением и перемонтированием инстанса?
JuniorТеорияЧастоКаковы основные фазы жизненного цикла классового компонента React?
Каковы основные фазы жизненного цикла классового компонента React?
У классового компонента три фазы. Монтирование вызывает constructor, getDerivedStateFromProps, render, затем componentDidMount. Обновление — shouldComponentUpdate, render, getSnapshotBeforeUpdate, затем componentDidUpdate. Размонтирование — componentWillUnmount.
Типичные ошибки
- ✗Запускать загрузку данных в
constructorилиrenderвместоcomponentDidMount - ✗Забывать очистку в
componentWillUnmount, утекая таймеры или слушатели - ✗Думать, что
componentDidMountснова выполняется на каждом обновлении
Уточняющие вопросы
- →Какой метод жизненного цикла — верное место, чтобы снять слушатель события?
- →Какие хуки заменяют
componentDidMountиcomponentWillUnmountв функциональных компонентах?
JuniorТеорияЧастоКакие аргументы принимает метод setState класса в React?
Какие аргументы принимает метод setState класса в React?
Первый аргумент — либо объект, сливаемый в state, либо функция-апдейтер (prevState, props) => partialState — форму с функцией берут, когда следующее состояние зависит от предыдущего, чтобы избежать багов устаревшего state.
Типичные ошибки
- ✗Передавать объект, когда следующий state зависит от предыдущего, теряя обновления при батчинге
- ✗Ожидать, что
this.stateсразу отразит новое значение послеsetState - ✗Думать, что
setStateзаменяет весь объект state, а не сливает его поверхностно
Уточняющие вопросы
- →Почему форма с функцией-апдейтером избегает багов устаревшего state, которые есть у формы с объектом?
- →Когда вы используете второй аргумент-колбэк вместо
componentDidUpdate?
JuniorТеорияЧастоЧто такое виртуальный DOM в React и зачем спискам нужен key?
Что такое виртуальный DOM в React и зачем спискам нужен key?
Виртуальный DOM — это лёгкое дерево в памяти, описывающее UI. На каждом рендере React сравнивает новое дерево с предыдущим (согласование) и применяет минимальные мутации реального DOM: разные типы элементов заменяют поддерево, одинаковые типы патчат props. key даёт каждому элементу списка стабильную идентичность, чтобы React сопоставлял элементы между рендерами, а не пересоздавал их, сохраняя state и избегая неверного переиспользования.
Типичные ошибки
- ✗Использовать индекс массива как
keyдля переупорядочиваемого или фильтруемого списка - ✗Думать, что виртуальный DOM сам по себе быстрее реального, а не слой сравнения
- ✗Считать, что согласование глубоко сравнивает всё, а не использует эвристики по типу/ключу
Уточняющие вопросы
- →Почему индекс массива как
keyрискован, когда элементы могут переупорядочиваться? - →Что делает React, когда тип элемента меняется между двумя рендерами?
MiddleТеорияЧастоВ React когда применять useMemo, useCallback и useEffect?
В React когда применять useMemo, useCallback и useEffect?
useEffect запускает побочные эффекты после рендера — подписки, запросы, работу с DOM — с очисткой при смене зависимостей или размонтировании. useMemo мемоизирует дорогое вычисленное значение между рендерами по его зависимостям. useCallback мемоизирует ссылку на функцию (частный случай useMemo), чтобы она оставалась стабильной для мемоизированных детей или зависимостей эффектов. Злоупотребление ими на дешёвых значениях стоит дороже, чем экономит.
Типичные ошибки
- ✗Оборачивать тривиально дешёвые значения в
useMemo, где накладные расходы больше выгоды - ✗Путать
useMemo(мемоизирует значение) сuseCallback(мемоизирует функцию) - ✗Ожидать, что
useEffectвыполнится до отрисовки, как синхронное вычисление
Уточняющие вопросы
- →Почему
useCallback(fn, deps)эквивалентенuseMemo(() => fn, deps)? - →Когда мемоизация значения вредит производительности вместо помощи?
MiddleТеорияЧастоПочему React считает setState асинхронным и что такое батчинг?
Почему React считает setState асинхронным и что такое батчинг?
Ради производительности React откладывает применение setState, а не меняет state и не перерендеривает тут же. Он собирает несколько обновлений из одного тика и сбрасывает их одним перерендером — это батчинг. React 18 авто-батчит и в промисах, и в таймерах.
Типичные ошибки
- ✗Читать
this.stateсразу послеsetStateи видеть старое значение - ✗Вызывать
setStateс объектом несколько раз, ожидая, что каждый применится отдельно - ✗Считать, что батчинг бывает только внутри обработчиков событий React даже на React 18
Уточняющие вопросы
- →Чем автоматический батчинг React 18 отличается от прежнего поведения?
- →Как прочитать зафиксированный state сразу после применения обновления?
JuniorТеорияИногдаЧто такое контейнерные и презентационные компоненты в React?
Что такое контейнерные и презентационные компоненты в React?
Презентационный («глупый») компонент отвечает лишь за то, как всё выглядит — берёт props и рисует разметку, почти без state и без логики данных. Контейнерный («умный») отвечает за то, как всё работает — грузит данные, читает store, обрабатывает события и кормит детей.
Типичные ошибки
- ✗Подмешивать загрузку данных в презентационный компонент, вредя переиспользованию
- ✗Считать, что различие в корневом теге JSX, а не в зоне ответственности
- ✗Принимать разделение за жёсткое правило, а не рекомендацию, дробя дерево
Уточняющие вопросы
- →Почему отсутствие данных в презентационном компоненте улучшает его переиспользование?
- →Как хуки размывают старую границу контейнер/презентация?
MiddleТеорияИногдаГде классу React грузить данные — в componentDidMount или componentWillMount?
Где классу React грузить данные — в componentDidMount или componentWillMount?
Используйте componentDidMount. Он выполняется после фиксации первого рендера, поэтому setState с данными запускает второй рендер, отрисовывающий результат. componentWillMount выполняется до первого рендера, где setState не планирует перерендер, и он устарел.
Типичные ошибки
- ✗Считать, что
setStateвcomponentWillMountпланирует перерендер - ✗Грузить внутри
render, запуская новый запрос на каждом рендере - ✗Использовать устаревший
componentWillMountв новом коде
Уточняющие вопросы
- →Почему
setStateвcomponentWillMountне вызывает видимого обновления? - →Какой массив зависимостей
useEffectвоспроизводит поведениеcomponentDidMount?
MiddleТеорияИногдаЧто будет, если задать key={Math.random()} компоненту в React?
Что будет, если задать key={Math.random()} компоненту в React?
Каждый рендер даёт новый случайный key, поэтому React видит другую идентичность каждый раз и размонтирует старый инстанс ради нового. Компонент теряет весь state, заново гоняет эффекты mount/unmount, теряет фокус и прокрутку и платит полную стоимость перемонтирования.
Типичные ошибки
- ✗Брать случайный или индексный key, чтобы заглушить предупреждение, вызывая перемонтирования или баги
- ✗Думать, что перемонтирование сохраняет state, раз рендерится тот же тип компонента
- ✗Считать, что
Reactсам игнорирует или стабилизирует недетерминированный key
Уточняющие вопросы
- →Почему key, меняющийся на каждом рендере, заставляет эффекты mount/unmount срабатывать снова и снова?
- →Что делает key хорошим и стабильным для списка записей?
SeniorДебаггингИногдаСделайте ревью этого компонента React: какие баги отметите?
Сделайте ревью этого компонента React: какие баги отметите?
Главный баг: у useEffect нет массива зависимостей, поэтому он перезапрашивает на каждый рендер — а каждый setLocation вызывает новый рендер, фактически цикл; задайте [props.locationId]. spotTimes — это МАССИВ объектов с одним ключом, но читается как spotTimes[s.id] — неверная форма; постройте один объект или Map по id. У <div> в map нет key, что ломает согласование. Мелочи: === и состояние загрузки для location.
Типичные ошибки
- ✗Упускать баг с отсутствием массива зависимостей, из-за которого эффект перезапрашивает на каждый рендер
- ✗Не замечать, что
spotTimes— массив объектов, но индексируется как карта по ключу - ✗Пропускать отсутствующий
keyу элементов списка изmap
Уточняющие вопросы
- →Почему эффект без массива зависимостей вместе с
setStateсоздаёт цикл перезапросов? - →Как переформировать
spotTimes, чтобыspotTimes[s.id]читался верно?
MiddleТеорияРедкоЧем useLayoutEffect отличается от useEffect в React?
Чем useLayoutEffect отличается от useEffect в React?
У обоих одинаковая сигнатура и семантика массива зависимостей, но выполняются они в разное время. useEffect выполняется асинхронно после отрисовки браузером, поэтому никогда не блокирует визуальные обновления — выбор по умолчанию для большинства эффектов.
Типичные ошибки
- ✗По умолчанию брать
useLayoutEffect, блокируя отрисовку там, где хватило быuseEffect - ✗Ожидать, что
useEffectвыполнится до отрисовки браузером - ✗Измерять раскладку в
useEffectи видеть мерцание до коррекции
Уточняющие вопросы
- →Почему измерение DOM-узла в
useEffectможет вызвать видимое мерцание? - →Почему злоупотребление
useLayoutEffectрискует ронять кадры?
SeniorТеорияРедкоКак хуки React устроены изнутри и почему Правила хуков?
Как хуки React устроены изнутри и почему Правила хуков?
React хранит хуки компонента упорядоченным списком (связным списком записей хуков) на его fiber. На каждом рендере он обходит этот список в порядке вызова, сопоставляя N-й вызов хука с N-й сохранённой записью, чтобы восстановить state. Имён нет — позиция и есть единственная идентичность.
Типичные ошибки
- ✗Думать, что хуки ключуются по имени, а не по порядку вызова
- ✗Вызывать хук внутри
ifили цикла, сдвигая последующие хуки на чужие записи - ✗Считать, что Правила хуков — лишь lint-соглашение по стилю
Уточняющие вопросы
- →Что конкретно ломается, если вызов
useStateобернуть вif? - →Почему два компонента могут переиспользовать один порядок хуков без коллизий?