Причины перерисовки компонентов в React
В React перерисовка (re-render) — это процесс, при котором компонент заново вызывается, чтобы React мог построить новое виртуальное дерево и сравнить его с предыдущим.
Разработчику важно понимать, что именно может вызвать перерисовку, чтобы оптимизировать производительность и избежать лишних обновлений.
Основные причины перерисовки
Изменение state
При вызове setState (например, setCount) компонент всегда перерисовывается.
const [count, setCount] = useState(0);
setCount(count + 1); // вызывает перерисовку
Изменение props
Если компонент получает новые значения пропсов, он тоже будет перерендерен.
<Child value={someValue} /> // если someValue изменился → ререндер
Родительский компонент перерендерился
Если родитель обновился, все его дочерние компоненты тоже вызываются снова,
если они не оптимизированы (React.memo, shouldComponentUpdate).
Изменение контекста (Context)
Если вы используете useContext, и значение контекста меняется —
все компоненты, которые его используют, перерисуются.
Принудительный ререндер (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 - Избегайте передачи новых объектов и функций без необходимости
Совет:
Оптимизируйте только те компоненты, которые реально создают нагрузку. Преждевременная оптимизация — зло.