Всем привет :) Хотел бы рассказать об использовании RTK Query + Redux Toolkit в больших проектах, а также ускорить вашу разработку и добавление новых страничек путем избавления от ненужных дублирований кода. Если ты frontend-разработчик на react, то, думаю, тебе не впервой сталкиваться с использованием RTK Query вместе с Redux Toolkit. Но даже если это не так, то мне есть что тебе показать ;) А если ты ни разу не сталкивался с этой связкой, то, возможно, после этой статьи задумаешься о её использовании. Рекомендуется скачать проект и по ходу чтения заглядывать в код, ибо некоторые моменты проще увидеть и понять, чем читать десятки слов и предложений. Установка зависимостей: yarn install. Запуск по команде: yarn dev. Необходимо постоянно писать лоадеры, которые бы показывали загрузку страницы, а затем отрисовывали бы полученные данные. Иногда хочется получить просто данные из запроса без создания отдельного слайса для страницы, а когда-то наоборот. Всегда необходимо думать об обработке неожиданных ошибок при добавлении новых страничек в сервис и отрисовывать окошко ошибки. При этом хочется избежать использования глобального обработчика. Если необходимы 2 и более запроса, то приходится отдельно прописывать логику и объединять запросы. А если один из них провалится, прописывать логику повторного запроса. При добавлении данных в слайс в методе onQueryStarted, данные просто не успевают попасть в хранилище до отрисовки компонента, который его использует. При запросе какой-либо мутации может инвалидироваться тег, что вызовет перезагрузку всей страницы, даже когда в этом нет необходимости. Спешу вас обрадовать, я эти проблемы решил, причем с минимальным количеством кода, поэтому давайте же перейдем к решению и самому проекту. Всю основную логику помещаем в папку redux. Разделяем api-запросы и слайсы по отдельным папочкам. Для лучшего понимания представляйте api как верхний слой над слайсами. Api работает, проводит какие-то свои манипуляции и кладет их в хранилище. Хранилищу необязательно знать, кто и что в него кладет, ему лишь надо знать, что сделать с данными. Api может обращаться к слайсам, но слайсы не могут обращаться к api.  Полезные для использование хуки и компоненты высшего порядка кладем в соответствующие папки hooks и hoc. Страницы в Next.js находятся в особенной папке pages. Все примеры использования в cat-facts/index.tsx При добавлении данных в слайс в методе onQueryStarted, данные просто не успевают попасть в хранилище до отрисовки компонента, который его использует. Переопределяем baseQuery и принимаем через аргументы метод onSuccess, который позволит нам помещать данные в хранилище, а после этого завершать загрузку. Не забываем вызов обернуть в try catch, чтобы видеть ошибки в консоли.   Необходимо постоянно писать лоадеры, которые бы показывали загрузку страницы, а затем отрисовывали бы полученные данные. Создаем специальный «хок», который будет делать запросы и выводить сообщения в случае ошибки. Логика его достаточно сложна, поэтому обратитесь к коду проекта. Находится в одноименной папке src/hoc. Можете адаптировать его под свою архитектуру проекта. Типизация при использовании работает отлично, однако от костыля при преобразовании к any, я так и не смог избавиться. Если кто-то знает, как решить, прошу Merge Request в репозиторий кинуть.  Если необходимы 2 и более запроса, то приходится отдельно прописывать логику и объединять запросы. А если один из них провалится, прописывать логику повторного запроса. Прежде чем использовать метод, создаем страничку, которая будет отрисовывать данные. Чтобы использовать данные от запросов, объединяем типы наших резолверов и наследуемся от них. Далее используем «хоки» для обработки запросов к api: withQueryResolver – содержит в себе самый главный запрос, который потом можно принять через аргументы и использовать данные. Вызывать можно только 1 раз и перед withOtherQueryResolver withOtherQueryResolver – содержит в себе второстепенный запрос, которые нельзя принять через аргументы. Обычно используется, чтобы какие-то дополнительные данные положить в хранилище (слайсы). Должен идти после withQueryResolver. Могут быть вызваны друг за другом несколько раз. При ошибке перезагрузка данных будет только у тех, что завершились ошибкой, а не у всех сразу. withMutationResolver – отвечает за обработку мутации, показа модалки загруузки, вывод модалки с ошибкой (если нужно). Можно адаптировать под свой проект. Как мы видим процесс загрузки и объединения запросов занимает всего 2 строчки, а подключение логики с обработкой мутации всего 1 строчку. И наконец прописываем страницу, которая будет экспортироваться во внешку: Все аргументы объединяются для каждого хука, поэтому можно избежать дублирования. При запросе какой-либо мутации может инвалидироваться тег, что вызовет перезагрузку всей страницы, даже когда в этом нет необходимости. Так как мы данные получаем из слайсов, то нам не нужно делать запрос заново, поэтому вызываем метод disableReload перед запросом мутации. В таком случаем при успешном вызове наш тег инвалидируется, но это не спровоцирует перезагрузку страницы. Метод showRetryModal используем, если хотим при ошибке показать модалку, что запрос не прошел и предложить повторить запрос. При таком подходе удается создать в проекте устойчивую к росту архитектуру и облегчить разработку. Давайте посмотрим, чего мы добились: При добавлении новой страницы нам необходимо написать всего 2-3 строчки и логика обработки запроса уже готова. Далее остается только написать контрол, который уже будет работать с этими данными. Теперь можно не бояться, что при какой-то неожиданной ошибке у нас вместо красивого сообщения об ошибке будет белый экран или еще чего страшнее. В случае изменения какого-то api метода, «хоки» начнут ругаться, что им передали контроллер, который принимает совсем другие данные, нежели те, что api-хук, а значит вероятность выпустить релиз с багами уменьшается в разы, ведь в production такое не скомпилируется. Благодаря объединению аргументов их можно использовать как в компоненте приемнике, так и в других методах api. Например, миграция одного аргумента метода к другому методу — дело 3 секунд. Добавление какого-то нового аргумента тоже менее болезненна, ведь если он передается для какого-то другого api метода, правки не нужны и typescript не будет ругаться. Если нам достаточно данных из хука, мы можем не создавать отдельный слайс под данные и, соответственно, не писать лишнего кода. Например, если наша страница всего лишь отображает данные, зачем писать для этого отдельный слайс? Можно просто взять готовые данные и отобразить. Вся логика обработки ошибок находится в одном едином месте. В будущем при необходимости мы можем легко добавить сбор какой-то статистики или еще что-то.  Full Stack программист