Hack Frontend Community

Причины перерисовки компонентов в React

В React перерисовка (re-render) — это процесс, при котором компонент заново вызывается, чтобы React мог построить новое виртуальное дерево и сравнить его с предыдущим.

Разработчику важно понимать, что именно может вызвать перерисовку, чтобы оптимизировать производительность и избежать лишних обновлений.


Основные причины перерисовки

1

Изменение state

При вызове setState (например, setCount) компонент всегда перерисовывается.

const [count, setCount] = useState(0);
setCount(count + 1); // вызывает перерисовку
2

Изменение props

Если компонент получает новые значения пропсов, он тоже будет перерендерен.

<Child value={someValue} /> // если someValue изменился → ререндер
3

Родительский компонент перерендерился

Если родитель обновился, все его дочерние компоненты тоже вызываются снова, если они не оптимизированы (React.memo, shouldComponentUpdate).

4

Изменение контекста (Context)

Если вы используете useContext, и значение контекста меняется — все компоненты, которые его используют, перерисуются.

5

Принудительный ререндер (force update)

Например, через useReducer, useSyncExternalStore или сторонние хранилища — можно вручную инициировать обновление компонента.

Как избежать лишних ререндеров

МетодЧто делает
React.memo(Component)Кэширует компонент, не обновляет без изменений props
useMemo(fn, deps)Кэширует вычисления между рендерами
useCallback(fn, deps)Кэширует функции, передаваемые вниз по дереву
useRef()Хранит данные без ререндера компонента
keyКонтролирует идентичность компонентов в списках

Пример лишнего рендера

function Parent() {
  const [count, setCount] = useState(0);

  return (
    <>
      <Child />
      <button onClick={() => setCount(count + 1)}>+1</button>
    </>
  );
}

function Child() {
  console.log("Child ререндерится");
  return <div>Я ничего не меняю</div>;
}

Даже если Child не использует count, он всё равно ререндерится, потому что родитель обновился.

Решение

const Child = React.memo(() => {
  console.log("Child ререндерится");
  return <div>Я ничего не меняю</div>;
});

Ловушка: новое значение по ссылке

const obj = { a: 1 };
<Component data={obj} />

Каждый раз создаётся новая ссылка, даже если данные те же → перерисовка. Используйте useMemo или useCallback, чтобы сохранить ссылку.

Итог

  • Компоненты в React ререндерятся при изменении state, props, context или родителя
  • Оптимизация возможна с помощью React.memo, useMemo, useCallback и useRef
  • Избегайте передачи новых объектов и функций без необходимости

Совет:

Оптимизируйте только те компоненты, которые реально создают нагрузку. Преждевременная оптимизация — зло.