Как организовать бизнес-логику в Redux
Что проверяют
Знаете ли вы, где в Redux живёт логика: в редьюсерах, селекторах, санках или middleware, и по какому признаку выбирать место. Отдельно смотрят, пишете ли вы на Redux Toolkit или на ручных switch из старых туториалов. Следом часто спрашивают, зачем Redux, если есть RTK Query или TanStack Query.
Как отвечать
Сразу обозначьте, что стандарт сейчас это Redux Toolkit: configureStore, createSlice с Immer внутри, хуки useSelector и useDispatch. Ручные константы типов и connect остались в старом коде.
Дальше распределите логику по местам:
- редьюсеры: основная синхронная логика. Официальный стайлгайд советует класть в них как можно больше правил: пересчёт итогов, проверку допустимости перехода. Редьюсер чистый, поэтому тестируется простым вызовом функции;
- действия как события:
cart/itemAdded, а неsetCartItems. Тогда несколько срезов реагируют на одно событие черезextraReducers, а компонент не решает, как именно меняется состояние; - селекторы: всё производное (сумма, фильтрация, доступность кнопки) считается в селекторах, тяжёлые мемоизируют через
createSelector. В сторе держат минимальное состояние; - санки: асинхронные сценарии и логика, которой нужен
getState, черезcreateAsyncThunk; - listener middleware: реакции вида «когда случилось X, сделай Y», например автосохранение или аналитика. Для сложных долгоживущих процессов в старых проектах встречается redux-saga;
- серверное состояние: данные с бэкенда лучше отдать RTK Query, а не держать вручную в срезах с флагами
loading.
Код группируют по фичам: срез, селекторы и санки одной области лежат рядом.
Где спотыкаются
Держат логику в компонентах, а в стор кладут готовый результат через setSomething. Redux превращается в глобальную переменную, а логику не проверить без рендера.
Кладут в стор производные данные рядом с исходными. Они расходятся при первом забытом обновлении, а селектор такого не допускает.
Путают Immer с разрешением мутировать: «мутирующий» код внутри createSlice безопасен, а тот же код в обычном редьюсере ломает обновление компонентов.