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

Как React понимает что нужно перерисовать компонент?

2.0 Middle🔥 231 комментариев
#React#Архитектура и паттерны

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Как React понимает, что нужно перерисовать компонент

Это один из ключевых механизмов React. Понимание того, как работает обнаружение изменений (change detection), критично для оптимизации производительности и написания эффективного кода.

Основной механизм: Virtual DOM и Reconciliation

React использует Virtual DOM — это JavaScript представление реального DOM. Когда что-то изменяется, React:

  1. Создает новый Virtual DOM
  2. Сравнивает (диффит) новый Virtual DOM со старым
  3. Вычисляет минимальный набор изменений
  4. Применяет изменения к реальному DOM

Этот процесс называется reconciliation или diffing.

Что триггерит перерисовку:

1. Изменение Props

function Counter({ count }) {
  return <div>{count}</div>;
}

// Когда родитель передает новый prop count, компонент перерисуется
<Counter count={5} />  // перерисовка
<Counter count={6} />  // перерисовка

2. Изменение State

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      {count}
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}
// При вызове setCount React понимает, что состояние изменилось

3. Перерисовка родителя

function Parent() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <Counter count={count} />
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  );
}
// Когда Parent перерисуется, Counter тоже перерисуется (даже если props не изменился)

Система сравнения (Diffing Algorithm):

React использует эффективный алгоритм диффинга:

По типу элемента

// Если типы разные, весь старый элемент заменяется
<div>Hello</div>  // старое
<span>Hello</span> // новое - полная замена, не обновление

По ключам (Keys)

// Правильно с ключами
{items.map(item => <Item key={item.id} item={item} />)}

// Плохо без ключей
{items.map((item, index) => <Item key={index} item={item} />)}
// Это может привести к неправильной перерисовке при добавлении/удалении

По атрибутам и содержимому

const el1 = <div className="active" title="test">Content</div>;
const el2 = <div className="active" title="test">Content</div>;
// React понимает, что это одно и то же, нет изменений

const el3 = <div className="inactive" title="test">Content</div>;
// Здесь className изменился, React обновит только этот атрибут

Оптимизация перерисовок:

useMemo — мемоизация вычислений

function ComplexComponent({ data }) {
  const expensiveValue = useMemo(() => {
    return data.filter(x => x.active).sort();
  }, [data]);
  
  return <div>{expensiveValue.length}</div>;
}

useCallback — стабилизация функций

function Parent() {
  const handleClick = useCallback(() => {
    console.log('clicked');
  }, []);
  
  return <Button onClick={handleClick} />;  // Reference не меняется
}

React.memo — для функциональных компонентов

const Counter = React.memo(({ count }) => {
  return <div>{count}</div>;
});
// Перерисовка происходит только если props изменился

Индикаторы перерисовки

function Counter({ count }) {
  console.log('Counter рендерится'); // Это выведется каждый раз
  return <div>{count}</div>;
}

Частые ошибки:

Создание объектов в render

// Плохо - каждый раз новый объект
function Component() {
  const style = { color: 'red' };
  return <div style={style}>Text</div>;
}

// Хорошо
const style = { color: 'red' };
function Component() {
  return <div style={style}>Text</div>;
}

Передача новых функций в props

// Плохо - новая функция каждый раз
<Button onClick={() => handleClick()} />

// Хорошо
const handleClick = useCallback(() => {...}, []);
<Button onClick={handleClick} />

Fiber Architecture (React 16+):

Внутри React использует Fiber архитектуру для более гибкого управления перерисовками. Это позволяет:

  • Разбивать работу на приоритеты
  • Прерывать и возобновлять работу
  • Обрабатывать срочные обновления (как клики) быстрее

Суть для собеседования:

React перерисовывает компонент когда:

  1. Props изменился — родитель передал другое значение
  2. State изменился — вызов setState
  3. Контекст изменился — значение Context Provider обновилось
  4. Родитель перерисовался — часто приводит к перерисовке детей

Оптимизация производительности — это управление этими перерисовками через React.memo, useMemo, useCallback и правильное структурирование компонентов.

Как React понимает что нужно перерисовать компонент? | PrepBro