Как использовать Redux и не облажаться

Redux — как перфоратор. Можно аккуратно повесить полку, а можно разнести всю стену вместе с соседями. Я видел проекты, где Redux добавляли «на всякий случай», а через полгода в сторе лежали и кэш сервера, и состояние кнопки «лайк», и даже текущее значение инпута. Хотите пользоваться Redux без боли? Вот 5 правил, которые вынесут вам мозг в правильном месте.

1. Не облажайтесь с выбором: Redux нужен только для ГЛОБАЛЬНОГО состояния

Ошибка новичка: положить в стор всё, что может понадобиться в двух компонентах.

Как не облажаться: Задайте вопрос — «Если это состояние изменится, должны ли об этом узнать компоненты, которые находятся в разных углах приложения и не связаны напрямую?»

✅ Да → Redux. ❌ Нет → useState, useReducer или поднятие состояния выше.

Плохой пример: isModalOpen в Redux. Хороший пример: данные текущего пользователя, тема оформления, корзина в интернет-магазине.

2. Не облажайтесь с мутациями (даже с Toolkit)

Redux Toolkit использует Immer, и это расслабляет. Вы начинаете писать state.user.name = ‘New’. И когда-нибудь сделаете это не в редьюсере, а где-нибудь в компоненте. И ничего не сломается… до поры до времени.

Как не облажаться: Запомните: изменять стейт можно ТОЛЬКО в редьюсерах/слайсах. В чистом виде никогда не пишите:

store.getState().user.profile.age = 30 //  ❌

Используйте селекторы для чтения и диспатчи для записи. Это железобетонное правило.

3. Не облажайтесь с производительностью

Redux сам по себе быстрый, но вы заставите его тормозить, если будете создавать новые ссылки на объекты каждую микросекунду.

Как не облажаться: Используйте createSelector (из reselect или из @reduxjs/toolkit). Мемоизация — ваш лучший друг, особенно когда массив из 500 постов после каждого изменения фильтра пересчитывается заново.

❌ Плохо:

const visibleTodos = useSelector(state =>    state.todos.filter(t => t.completed === state.filter) )

✅ Хорошо:

const selectVisibleTodos = createSelector(   state => state.todos,   state => state.filter,   (todos, filter) => todos.filter(t => t.completed === filter) ) // и в компоненте: const visibleTodos = useSelector(selectVisibleTodos)

4. Не облажайтесь с асинхронщиной Самые частые грабли — забыть, что редьюсер должен быть синхронным. Начинающие пишут dispatch(fetchUser()) и пытаются в редьюсере дождаться ответа.

Как не облажаться: Простой вариант: createAsyncThunk из Redux Toolkit. Продвинутый: RTK Query (если данные с бэка — это вообще отдельная песня, лучше сразу на него переходить). И обязательно обрабатывайте три состояния: pending, fulfilled, rejected. Не оставляйте пользователя в подвешенном состоянии без лоадера и без ошибки.

5. Не облажайтесь с архитектурой: не делайте Redux «мусоркой»

Я видел стор, в котором были: isSidebarOpen isMobileKeyboardVisible lastScrollPosition currentInputValueInForm Это не Redux, это ад канцелярита.

Как не облажаться: Разделяйте данные на категории: Доменные данные (пользователи, товары, заказы) → Redux. Состояние UI, которое локально (открыт/закрыт дропдаун, значение поля) → локальный стейт компонента. Кэш сервера → RTK Query (или TanStack Query), а не ручное складывание в Redux.

Бонус-совет: не используйте Redux, если… …вы пишете лендинг, небольшой дашборд на 3 экрана или прототип за выходные. Тогда «не облажаться» проще всего — просто возьмите Zustand или Context. Redux включайте, когда реально начинает не хватать: строгой предсказуемости, time-travel отладки, жёстких контрактов для команды из 5 человек.

Итого Redux — мощный инструмент, но он может покарать за небрежность . Следуйте пяти правилам, и он станет вашим надёжным бэкендом на фронте😁. А если однажды поймаете себя на мысли «а зачем я это положил в стор» — значит, вы уже на пути джедая.

А с какими подводными камнями при использовании Redux сталкивались вы? Делитесь в комментариях — предупреждён значит вооружён ✊