Как называется алгоритм сравнения деревьев в React
Что проверяют
Знаете ли вы, что React не сравнивает деревья «честно», а опирается на эвристики, и понимаете ли, как эти эвристики влияют на ваш код. Следом почти всегда спрашивают про key в списках и про то, почему индекс в роли ключа это плохая идея.
Как отвечать
Процесс называется reconciliation (согласование), а само сравнение старого и нового дерева элементов называют diffing. Общий алгоритм сравнения двух деревьев работает за O(n³), React укладывается в O(n) за счёт допущений:
- разные типы дают разные деревья: если на месте
<div>появился<section>или другой компонент, React размонтирует старое поддерево целиком, со всем состоянием, и строит новое; - одинаковый тип: у DOM-элемента обновляются только изменившиеся атрибуты, у компонента сохраняется экземпляр и состояние, меняются пропсы;
- списки: дочерние элементы сопоставляются по
key. Без ключей React сравнивает по позиции, и вставка в начало списка заставляет обновить всё.
Отдельно назовите Fiber. Это не алгоритм сравнения, а архитектура реконсилера с React 16: работа разбита на единицы, фаза render может прерываться и получать приоритеты, а фаза commit применяет изменения к DOM за один проход. На этом построен конкурентный рендеринг и useTransition.
Сильный ответ связывает теорию с практикой: ключ должен быть стабильным идентификатором из данных, а сброс состояния можно устроить намеренно, поменяв key у компонента.
Где спотыкаются
Называют алгоритмом Fiber или виртуальный DOM. Виртуальный DOM это модель данных, Fiber это устройство движка, а сравнение по эвристикам происходит внутри reconciliation.
Считают индекс в роли ключа проблемой только производительности. При удалении или сортировке состояние уезжает к соседнему элементу: введённый текст оказывается в чужой строке.
Объявляют компонент внутри другого компонента. На каждом рендере это новый тип, поэтому поддерево пересоздаётся, а поле ввода теряет фокус и значение.