Что такое reconciliation в React и как он работает
Что проверяют
Понимаете ли вы эвристики сравнения деревьев и роль key. Это то, что напрямую влияет на баги с состоянием списков.
Как отвечать
Согласование это процесс, в котором React сравнивает новое дерево элементов со старым и вычисляет минимальный набор изменений настоящего DOM.
Полное сравнение двух деревьев стоит O(n³), поэтому React использует эвристики и укладывается в O(n):
- разный тип элемента означает полное пересоздание:
divзаменили наspan, значит старое поддерево уничтожается вместе с состоянием, новое создаётся с нуля; - сравнение идёт по позициям, если нет ключей. Вставка элемента в начало списка сдвигает всё и приводит к перерисовке каждого элемента;
keyдаёт элементу идентичность. По ключам React понимает, что элемент переехал, а не изменился, и переиспользует и узел DOM, и состояние компонента.
Отсюда классическая ошибка: индекс массива в качестве ключа. При вставке в начало у элементов меняется соответствие ключей и данных, и введённый текст, фокус или анимация уезжают к соседу. Ключ должен быть стабильным идентификатором данных.
Полезно добавить про современную реализацию: начиная с React 18 работа разбита на части и может прерываться, чтобы не блокировать интерфейс на длинных обновлениях. Отсюда возможность помечать обновления как несрочные через useTransition.
Где спотыкаются
Ставят индекс в key и потом ищут, почему состояние строк перепутывается.
Считают, что React сравнивает настоящий DOM, а не деревья элементов.
Не понимают, почему смена типа обёртки сбрасывает состояние всего поддерева.
Уверены, что виртуальный DOM сам по себе делает приложение быстрым.