Как избежать ререндер компонента?
Рендеринг и производительность
Избежать лишнего ререндера можно двумя классами приёмов: архитектурными (изменить структуру, чтобы рендер не запускался) и мемоизационными (научить компонент пропускать рендер).
Архитектурные приёмы — пробовать первыми
Спустить состояние вниз. Часто меняющийся state держать в маленьком компоненте:
// ❌ ввод в поиске рендерит всю страницу
const Page = () => {
const [query, setQuery] = useState('');
return (<><Search value={query} onChange={setQuery} /><HeavyContent /></>);
};
// ✅ состояние живёт внутри Search — страница не рендеритсяchildren как проп. Обёртка со state не перерендеривает готовых детей:
const Panel = ({ children }) => {
const [open, setOpen] = useState(true);
return <div>{open && children}</div>; // children стабильны
};Разделить контексты по частоте изменений; мемоизировать value провайдера.
Узкие подписки на стор: селектор выбирает минимум (s.items.length, а не весь s).
Мемоизационные приёмы
React.memo(Component)— пропуск рендера при тех же props.useCallback/useMemoу родителя — стабильные ссылки для props memo-ребёнка (без них memo не работает; children тоже ломает сравнение).- В классах — PureComponent/shouldComponentUpdate.
Чего не делать
- Не мемоизировать всё подряд «на всякий случай» — усложнение без выигрыша.
- Не хранить в state производные данные — вычислять в рендере/useMemo.
- Не создавать компоненты внутри рендера — каждый раз новый тип, пересоздание поддерева.
Коротко для собеседования
Сначала архитектура: состояние вниз к месту использования, children-как-проп, раздельные мемоизированные контексты, узкие селекторы. Затем точечно React.memo + useCallback/useMemo для стабильных props. Проверять результат профайлером, а не на глаз.