Проверяет понимание жизненного цикла React при изменении состояния и причин потери фокуса при повторном рендере.
Когда вызывается setState или useState-сеттер, React помечает компонент как требующий обновления и планирует повторный рендер. Вместо немедленного изменения DOM React создаёт новое виртуальное дерево элементов, описывающее желаемый интерфейс. Затем происходит процесс согласования (reconciliation): React сравнивает новое виртуальное дерево с предыдущим и вычисляет минимальные изменения для реального DOM.
На этапе сравнения React использует эвристики: если тип элемента (например, div или input) совпадает, он обновляет только изменённые свойства; если тип отличается, старый узел удаляется и создаётся новый. Ключевой момент — наличие атрибута key. Если key у элемента меняется или отсутствует, React может пересоздать узел, даже если структура похожа.
Фокус — это состояние браузера, привязанное к конкретному DOM-узлу. Когда React удаляет узел и создаёт новый (например, из-за изменения key или типа), браузер теряет ссылку на старый узел, и фокус сбрасывается. Даже если новый элемент выглядит идентично, он не получает фокус автоматически, потому что браузер не знает, что нужно его установить.
Рассмотрим пример: список инпутов, где при добавлении нового элемента в начало списка React пересоздаёт все элементы, если key не задан или задан по индексу. В результате пользователь теряет фокус на текущем поле ввода.
function App() {
const [items, setItems] = useState(['a', 'b']);
const addItem = () => setItems(['new', ...items]);
return (
<div>
{items.map((item, index) => (
<input key={index} defaultValue={item} />
))}
<button onClick={addItem}>Add</button>
</div>
);
}Здесь key={index} приводит к тому, что при добавлении элемента в начало все инпуты получают новые key (0,1,2 вместо 0,1), поэтому React пересоздаёт каждый узел. Фокус теряется. Правильное решение — использовать стабильный уникальный идентификатор:
const [items, setItems] = useState([{id: 1, value: 'a'}, {id: 2, value: 'b'}]);
// key={item.id} — тогда React обновит только новые элементы, а существующие останутся нетронутымиВ случаях, когда элемент появляется условно, можно использовать ref и в эффекте вызывать focus(). Это гарантирует, что после монтирования нового узла фокус будет установлен.
Вывод: потеря фокуса в React — следствие пересоздания DOM-узлов. Применяйте стабильные key и минимизируйте изменения структуры, чтобы сохранить пользовательский ввод и фокус. Если пересоздание неизбежно, явно управляйте фокусом через ref и эффекты.
Frontend developer
Ментор по Frontend
Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства
Записаться на консультацию