← Назад к вопросам

Когда происходит контроль изменений в VDOM?

2.2 Middle🔥 151 комментариев
#ООП#Фреймворки и библиотеки

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда происходит контроль изменений в VDOM?

VDOM (Virtual DOM) — это абстрактное представление реального DOM в памяти. React использует VDOM для оптимизации обновлений UI. Давайте разберёмся, когда именно происходит контроль изменений.

Жизненный цикл VDOM обновлений

1. Trigger (Триггер) 2. Render phase (синхронный, может быть прерван) 3. Reconciliation (сравнение VDOM) 4. Commit phase (применение изменений в DOM) 5. Layout & Paint 6. Browser repaint

1. Trigger — что вызывает контроль изменений?

  • setState вызывает контроль изменений
  • props изменились
  • Прямое изменение DOM (но это плохо)
  • Обычное переприсваивание НЕ работает в React

2. Render Phase (Синхронный)

В этой фазе React:

  • Вызывает функцию компонента (функциональный компонент)
  • Вызывает render() метод (классовый компонент)
  • Создаёт новый VDOM tree

Важно: Render phase может быть прерван (Concurrent features в React 18+).

3. Reconciliation — контроль изменений (Diffing)

React сравнивает старый VDOM с новым:

Алгоритм:

  • Если type изменился — замени весь узел
  • Если props изменились — обнови props
  • Рекурсивно сравни children

Контроль по ключам (keys):

  • Правильно: key={item.id} (уникальный ключ)
  • Неправильно: key={index} (может спутать элементы)

Без key с индексом: [A, B, C] → [B, C] → React может подумать что A → B, B → C, C удалён Это приводит к неправильному обновлению.

4. Commit Phase — применение в DOM

Здесь React:

  • Удаляет узлы из DOM
  • Добавляет новые узлы
  • Обновляет props в реальном DOM
  • Запускает lifecycle методы (useEffect, componentDidMount и т.д.)

Порядок:

  1. Render phase (функция вызывается)
  2. Reconciliation (сравнение VDOM)
  3. Commit phase (DOM обновляется)
  4. useEffect выполняется

Batch updates (React 18+)

React объединяет несколько setState в один Render плюс Commit:

function handleClick() {
  setCount(c => c + 1);
  setName('John');
  // Оба setState объединены в один цикл
  // Контроль изменений произойдёт один раз!
}

Но в асинхронном коде это не работает:

setTimeout(() => {
  setCount(c => c + 1); // Один render
  setName('John');      // Второй render (два раза проверка!)
}, 0);

Shallow comparison (поверхностное сравнение)

React сравнивает поверхностно:

const oldProps = { user: { name: 'John' } };
const newProps = { user: { name: 'John' } };

oldProps.user === newProps.user // false (разные объекты в памяти!)
// React подумает что props изменились

Правильно — используй useMemo:

const user = useMemo(() => ({ name: 'John' }), []);
// Теперь объект не пересоздаётся каждый раз

Оптимизация контроля изменений

1. React.memo — пропустить render если props не изменились

const MyComponent = React.memo(({ name }) => <div>{name}</div>);

2. useMemo — кэшировать вычисления

const memoizedValue = useMemo(() => expensiveCalculation(), [deps]);

3. useCallback — кэшировать функцию

const memoizedCallback = useCallback(() => { ... }, [deps]);

4. Правильные keys в списках

<ul>
  {items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>

Контроль изменений в классовых компонентах

class Counter extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    // Контроль: обновлять ли компонент?
    if (nextState.count === this.state.count) {
      return false; // Не обновлять
    }
    return true;
  }
}

Итог

Контроль изменений в VDOM — это:

  1. Быстро — только нужные части DOM обновляются
  2. Автоматически — React управляет процессом
  3. Оптимизируемо — используй memo, useMemo, useCallback
  4. Предсказуемо — правильные keys и shallow comparison