intermediate
Selectors
Инкапсулируйте чтение, стройте view model и мемоизируйте дорогие проекции при стабильных входах.
Селекторы инкапсулируют чтение и производные проекции из store. Простые читают slice; мемоизированные (reselect) пересчитываются только при смене ссылок или значений входов.
import { createSelector } from '@reduxjs/toolkit';
const selectTodos = (state) => state.todos;
const selectActiveTodos = createSelector([selectTodos], (todos) =>
todos.filter((t) => !t.done),
);
Держите селекторы рядом со slice. View-компоненты не должны знать форму store — они вызывают `selectCartTotal(state)` или `useSelector(selectCartTotal)`.
Компромисс: инкапсулированное чтение и мемоизация против памяти под кэши и сложности при нестабильных входах.
На интервью: когда мемоизация помогает, а когда добавляет overhead; как нормализация переносит работу в селекторы.
Типовые ошибки: inline стрелки в `useSelector` с новой ссылкой каждый render, селекторы, мутирующие state, вычисления в компонентах вместо общих селекторов.
Чеклист:
- Скрывайте форму store за селекторами.
- Мемоизируйте тяжёлые join и filter.
- Стабильные ссылки селекторов для useSelector.
- Тестируйте селекторы как чистые функции.