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

В каких случаях useSelector будет вызывать перерисовку компонента?

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

useSelector (react-redux) вызывает перерисовку, когда результат селектора для нового состояния стора отличается от прошлого результата по строгому сравнению (=== / Object.is).

Механика

При каждом dispatch стор уведомляет подписчиков; useSelector прогоняет свой селектор по новому state и сравнивает результат с прошлым:

  • результат тот же (по ссылке/значению) → ререндера нет;
  • отличается → компонент перерисовывается.
const count = useSelector((s) => s.cart.items.length); // примитив — надёжно

Когда будут ЛИШНИЕ перерисовки

Селектор возвращает новый объект/массив каждый вызов:

// ❌ map создаёт новый массив при КАЖДОМ dispatch — ререндер всегда
const titles = useSelector((s) => s.items.map((i) => i.title));

// ❌ объект-литерал — та же проблема
const data = useSelector((s) => ({ user: s.user, cart: s.cart }));

Любой dispatch (даже не связанный с этими данными) даст новую ссылку → перерисовку.

Слишком широкий селектор:

const state = useSelector((s) => s); // перерисовка на каждое изменение стора

Как чинить

  • Выбирать минимум: примитивы и готовые ссылки из стора (s.user.name).
  • Несколько маленьких useSelector вместо одного «объекта всего».
  • shallowEqual вторым аргументом для объектов: useSelector(sel, shallowEqual).
  • Мемоизированные селекторы (createSelector из reselect): пересчёт и новая ссылка — только когда изменились входы.

Коротко для собеседования

useSelector перерисовывает компонент, когда результат селектора изменился по строгому равенству после dispatch. Классическая ошибка — селектор, создающий новый объект/массив на каждый вызов (map, литералы): ререндер на любой dispatch. Лечение: узкие селекторы-примитивы, shallowEqual, createSelector.

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