PassFront
  1. PassFront
  2. База знаний
  3. Рендеринг и производительность

Как избежать ререндер компонента?

Рендеринг и производительность

Избежать лишнего ререндера можно двумя классами приёмов: архитектурными (изменить структуру, чтобы рендер не запускался) и мемоизационными (научить компонент пропускать рендер).

Архитектурные приёмы — пробовать первыми

Спустить состояние вниз. Часто меняющийся 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. Проверять результат профайлером, а не на глаз.

Другие вопросы раздела