Как избежать лишних перерисовок в React-приложениях с помощью React.memo
и хука useCallback
.
Часто при обновлении состояния в родительском компоненте все дочерние компоненты тоже ререндерятся, даже если их пропсы не изменились. Это снижает производительность и может привести к «тормозам» на крупных страницах.
1. Оборачиваем «тяжёлые» компоненты в React.memo
.
2. Меммоизируем функции-колбэки через useCallback
, чтобы их ссылки не менялись без нужды.
import React, { useState, useCallback, memo } from 'react';
const Child = memo(({ onClick, label }) => {
console.log('Child rendered');
return <button onClick={onClick}>{label}</button>;
});
function Parent() {
const [count, setCount] = useState(0);
// Функция останется той же, если зависимости не изменятся
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<Child onClick={handleClick} label="Нажми меня" />
<button onClick={() => setCount(prev => prev + 1)}>
Счётчик: {count}
</button>
</div>
);
}
*
React.memo
сравнивает предыдущие и новые пропсы поверхностно и рендерит Child
только когда они реально отличаются.*
useCallback
гарантирует, что ссылка на handleClick
не меняется при каждом рендере Parent
, а значит Child
не получает «новый» проп и не перерисовывается.Когда это не работает?
Если вы передаёте в пропы объекты или массивы, создаваемые «на лету», их тоже нужно мемоизировать через
useMemo
.Для функций с зависимостями важно корректно указать массив зависимостей, иначе обновления могут «застрять».
Попробуйте применить эти приёмы в своём проекте и посмотрите в консоли, как уменьшится количество ререндеров.
👉 @frontend_1
>>Click here to continue<<
