Redux - это инструмент для управления состоянием данных и состоянием пользовательского интерфейса в приложениях Javascript. В этом руководстве мы увидим, как организовать структуру проектов, состоящих из Redux.
Redux - это контейнер с предсказуемым состоянием для приложений JavaScript. Он помогает вам писать приложения, которые ведут себя согласованно, работают в разных средах (клиентских, серверных и собственных) и легко тестируются. - https://redux.js.org/
Хотя Redux в значительной степени связан с React, его также можно использовать с другими библиотеками, такими как Vue, Meteor, Angular и т. Д. Он также легкий, около 2 КБ (включая зависимости), поэтому вам не нужно беспокоиться о размере приложения. слишком большой.
Поскольку мы избавились от определения Redux, давайте приступим к разработке протестированной, строго типизированной и масштабируемой архитектуры!
Если вы хотите перейти непосредственно к спецификациям архитектуры, перейдите в раздел Архитектура проекта Redux. Вы также можете посмотреть репо, которое я создал для этого урока, отсюда.
СОДЕРЖАНИЕ
Предпосылки
Node v10.x.x
Настройка проекта
Для начала мы будем использовать create-react-app
with typescript, но эту архитектуру также можно применить к любому существующему проекту:
$ yarn create react-app my-app --typescript
Затем мы можем перейти в каталог проекта и запустить приложение:
$ yarn start
Установка зависимостей
Очевидно, нам нужно установить зависимости, связанные с redux, в базе кода в другой командной строке в корневом каталоге проекта:
$ yarn add [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]
Давайте также добавим зависимости разработки:
$ yarn add --dev @types/react-redux@
7.1.1 @types/[email protected] @types/[email protected] @types/[email protected]
Интеграция Redux в проект
После установки нам нужно внести пару изменений в существующий код, чтобы подготовить базу кода для архитектуры Redux. Сначала удалите всю разметку внутри return
. Затем добавьте разметку для поставщика redux с хранилищем redux и контейнером. Итоговый файл App.tsx будет выглядеть так:
Затем мы создадим state
folder внутри src
directory, чтобы сохранить файл конфигурации нашего хранилища и инициализацию для хранилища Redux.
$ mkdir src/state && touch src/state/index.ts
Чтобы иметь возможность настраивать промежуточное ПО в зависимости от среды, давайте создадим индексный файл, который будет импортировать конфигурацию хранилища. В этом руководстве мы останемся в среде разработки:
Затем нам нужно создать конфигурацию разработки инициализатора хранилища в том же каталоге:
В целях модульности состояний мы будем придерживаться подхода к структуре папок на основе функций. Что называется Утки. Подробнее об этом шаблоне можно узнать здесь: freeCodeCamp: https://www.freecodecamp.org/news/scaling-your-redux-app-with-ducks-6115955638be/
Итак, давайте создадим нашу первую папку с утками, в которой будут храниться другие утки (папки функций):
$ mkdir src/state/ducks && touch src/state/ducks/index.ts
Затем нам нужно создать корневой редуктор, который определяет состояние приложения:
Архитектура проекта Redux
Архитектура Redux основана на строгом однонаправленном потоке данных.
Это означает, что все данные в приложении подчиняются одному и тому же шаблону жизненного цикла, что делает логику вашего приложения более предсказуемой и простой для понимания. Это также способствует нормализации данных, так что вы не получите несколько независимых копий одних и тех же данных, которые не знают друг о друге. - https://redux.js.org/basics/data-flow
В этой архитектуре поток данных выглядит следующим образом:
- Компонент обрабатывает событие и отправляет действие
- Redux вызывает функции редуктора
- Связанная функция редуктора обновляет состояние
- Контейнеры, которые ожидают изменения этого сегмента состояния, получают уведомление
- Контейнеры обновляют компонент с новым состоянием и реквизитами
- Компонент перерисовывается при изменении реквизита
Между тем, саги прислушиваются к определенным действиям и устраняют побочные эффекты. По продукту он будет отправлять новые действия.
Продолжим реализацию потока данных. Во-первых, нам нужен один общедоступный API. Для этого воспользуемся JSONPlaceholder.
Чтобы сохранить URL-адрес api, нам нужно создать файл .env. Не забудьте перезапустить сервер npm после добавления следующих строк:
// .env REACT_APP_JSON_PLACEHOLDER=https://jsonplaceholder.typicode.com
Для простоты в этом руководстве мы реализуем только запрос GET. Но вы можете легко выполнить POST, создав новые действия, которые несут полезную нагрузку для отправки в конечную точку API. Чтобы сделать его типизированным, вы также должны изменить типы действий на основе этого. Исходя из этого, наша масштабируемая архитектура и структура папок выглядят так:
src ├── App.css ├── App.test.tsx ├── App.tsx ├── components │ ├── post.tsx │ └── postList.tsx ├── containers │ ├── __tests__ │ │ └── postList.container.spec.tsx │ └── postList.tsx ├── index.css ├── index.tsx ├── logo.svg ├── react-app-env.d.ts ├── serviceWorker.ts └── state ├── configureStore.dev.ts ├── ducks │ ├── index.ts │ └── post │ ├── __tests__ │ │ ├── __mockData__ | | | └── postsData.json | │ ├── actions.spec.ts │ │ ├── reducers.spec.ts │ │ └── sagas.spec.ts │ ├── actions.ts │ ├── reducers.ts │ ├── sagas.ts │ └── types.ts ├── index.ts ├── middlewares │ └── saga.ts └── utils └── apiCaller.ts
Поскольку у нас будут операции для posts
в нашем API, имя папки будет называться post. Также внутри него будет создана папка с тестовыми и макетными данными:
$ mkdir src/state/ducks/post src/state/ducks/post/__tests__ src/state/ducks/post/__tests__/__mockData__
Кроме того, нам нужно хранить в этой папке связанные типы для этой функции. Добавьте связанные типы в файл типов: type
Нам потребуются фиктивные данные для нашей post
feature, которые выглядят так:
Действия
Мы начнем с написания наших действий для нашей post
feature. Для простоты мы не будем рассматривать обработку ошибок в этом руководстве. Сначала мы начнем писать тесты:
Затем напишите фактические действия:
Редукторы
Нам нужны редукторы для формирования нашего состояния. Приступим к реализации с тестов:
Фактический редуктор будет выглядеть так:
Таким образом, redux настроен и готов к использованию. Следующий шаг - как бороться с побочными эффектами.
Промежуточное ПО
Поскольку мы хотим, чтобы наши действия и редукторы были чистыми, нам нужно разобраться с этим в другом месте. Лучше всего использовать какое-то промежуточное программное обеспечение, которое может прослушивать действия и отправлять другие действия в Redux. Есть несколько вариантов, но для этого урока мы будем использовать Redux-Saga. Здесь мы также будем выполнять наши вызовы Ajax.
Для хранения промежуточного программного обеспечения мы создадим новую папку с именем middlewares
внутри state
directory:
$ mkdir src/state/middlewares && touch src/state/middlewares/sagas.ts
Давайте создадим промежуточное ПО для саги, чтобы использовать его при инициализации нашего магазина:
Чтобы использовать Redux-saga, нам нужно добавить наше новое промежуточное ПО для хранения конфигурации следующим образом:
Как всегда, начнем с написания тестов. С redux-saga-test-plan
package писать тесты для саг довольно просто:
Далее мы напишем нашу первую сагу для прослушивания определенных действий:
Нам также нужно создать одну корневую сагу, чтобы разветвить все саги о функциях в нашей базе кода:
Звонки Ajax
Мы начнем с создания новой папки, в которой будут храниться наши государственные утилиты:
$ mkdir src/state/utils && touch src/state/utils/apiCaller.ts
Для вызова API мы будем использовать встроенный метод fetch
. Мы реализуем это, создав служебную функцию с именем apiCaller
.
Контейнеры
Рекомендуется различать компоненты контейнера и компоненты представления. Компоненты контейнера служат мостом между хранилищем Redux и компонентами презентации. Компоненты контейнера получают данные из хранилища redux и предоставляют данные и действия для презентационных компонентов. Они, как правило, сохраняют состояние.
Поскольку контейнеры могут прослушивать более одного среза состояния, они должны переходить в свой собственный каталог.
$ mkdir src/containers src/containers/__test__
Начнем сначала писать тесты для контейнера:
Далее идет фактический код контейнера:
Завершим это созданием компонентов презентаций:
$ mkdir src/components
На этом мы завершили поток данных и архитектуру Redux. Независимо от того, сколько функций вы добавите в эту кодовую базу, сложность останется почти такой же.
Что следующее?
Есть некоторые инструменты и зависимости, которые вы можете установить и использовать в качестве промежуточного программного обеспечения, чтобы упростить разработку и помочь новичкам быстрее адаптироваться.
- редуктор-регистратор
- сокращение-devtools-расширение
Заключение
Продвигаясь вперед, мы прилагаем все усилия, чтобы разработать проекты в соответствии с нашими потребностями. Это делает наши проекты более устойчивыми. Делая это, мы изучаем и обобщаем то, что мы узнали, чтобы мы могли повторно использовать и улучшать в наших будущих проектах.
Redux прошел долгий путь и все еще остается сильным. Redux по-прежнему популярен и широко используется во многих производственных проектах. Эта архитектура, которую мы используем, все еще актуальна и правильно выполняет свою работу. Я надеюсь, что это руководство поможет вам в следующем проекте.
Ваше здоровье!