Reeeewind
Redux - это система управления состоянием. Заинтригованы? Читать дальше
Сложность: Начинающий | Легко | Нормальный | Испытывающий
Эта статья была разработана с использованием Xcode 11.4.1 и Swift 5.2.2.
Эта статья была обновлена для Xcode 12.4 и Swift 5.3.2.
Предпосылки:
- Кодирование в Swift Playgrounds (гайд ЗДЕСЬ)
Терминология:
Redux: библиотека JavaScript с открытым исходным кодом для управления состоянием приложения
Использование Redux в проектах
Преимущества:
- Функции чистого редуктора упрощают тестирование бизнес-логики
- Централизация состояния упрощает отладку
- Приветствуется нормализация данных. Конечным результатом является то, что у вас не будет нескольких независимых копий одних и тех же данных, которые не знают друг друга и не могут быть легко обновлены.
- Состояние может быть сохранено в локальном хранилище, которое затем можно использовать для загрузки или возврата приложения в это состояние.
- Поскольку redux строго относится к организации кода, у нас есть преимущества, которые дает обслуживание кода.
- Легко отлаживать
Недостатки:
- Само состояние неизменяемо и может быть обновлено только редуктором. Это само по себе может увеличить требования к памяти системы.
- Ограниченный дизайн со стандартным кодом
- Жесткость и сложность, которые делают redux подходящим для очень больших проектов, означает, что он часто не подходит для многих небольших проектов.
- Действия не связаны с их эффектами (которые хранятся в редукторе)
Вам вообще нужен Redux?
Одним из основных недостатков Redux является то, что он может вам не понадобиться в вашем проекте (по крайней мере, пока). Так как же узнать, действительно ли вашему приложению требуется Redux?
- У вас есть большое состояние приложения, которое требуется во многих частях вашего приложения
- Состояние вашего приложения часто обновляется
- Состояние вашего приложения сложно обновить
- Ваше приложение имеет кодовую базу среднего и большого размера, над которой работают многие люди.
- Вам нужно видеть, как состояние обновляется с течением времени
Компоненты Redux
Состояние: состояние приложения, которое считается источником истины. Хотя может быть только одно состояние, его можно разделить на подсостояния.
Действия: объекты, описывающие, что может делать система. Отправляется представлением как намерение изменить состояние приложения.
Редукторы: основная логика приложения и создание нового состояния для приложения с учетом действия и текущего состояния. Они должны быть чистыми функциями без побочных эффектов и синхронными (это затронуто в заключении, но именно поэтому этот пример проекта не содержит никаких сетевых функций).
Связь с МВИ
Здесь есть связь с Android, а точнее с MVI.
Итак, Redux на самом деле является MVI, потому что редуктор - это модель, действия - это намерение, а состояние - это… redux
Управление компонентами пользовательского интерфейса
Обновление компонента пользовательского интерфейса может быть выполнено с помощью хранилища Redux, возможно, с сохранением текста внутри метки.
Redux:
- Вызов действия
- Передать данные редуктору
- Обновите магазин
Императив:
- Поддерживать локальную переменную состояния
Решение состоит в том, что оставить в запасе, а что выбрать в состоянии (и даже думать об этом как о битве между декларативным и императивным программированием). Соблазн держать все в состоянии велик, но для (тривиальных?) Элементов пользовательского интерфейса нет смысла перегружать состояние каждым компонентом.
Пример проекта
Создание проекта
Мы создаем проект единого представления, а затем используем Swift Package Manager, чтобы включить зависимость от https://github.com/ReSwift/ReSwift (до следующего основного).
Функциональные возможности приложения
Это конкретное приложение будет иметь множество людей
let people: [Person] = [Person(name: “James”), Person(name: “Ahmed”)]
и будет отображать имя человека по одному, начиная с первого человека. При нажатии кнопки next
отображается следующий человек в списке.
Да это некрасиво.
Да, это просто UILabel
на контроллере представления с UIButton
внизу. Здесь нет ничего интересного - это статья об архитектуре, так что, пожалуйста, потерпите меня.
Код
Обратите внимание, что большинству (если не всем) из этих классов потребуется import ReSwift
- так что с учетом сказанного давайте намочим ноги!
Есть основной магазин, который я поместил в Constants.swift
файл. Здесь также можно объявить middleware
.
AppState - это то место, где находится основная часть этого проекта - здесь у нас есть array
человека и currentIndex
, который действует как указатель на соответствующего человека в списке.
Это подключается к Person
struct
просто содержит имя каждого Person
Редуктор - это бизнес-логика приложения, а также инициализирует исходное состояние, если оно не указано при вызове reducer
.
Действие довольно тривиально struct
, как показано в следующем фрагменте кода.
это связано с помощью следующего ViewController
. Обратите внимание, как он соответствует StoreSubscriber
protocol
, что означает, что мы должны добавить typealias
, как показано во фрагменте кода. Действие кнопки создает dispatch
действие, которое поражает редуктор - фантастика! Когда редуктор выполняет свою работу, он попадает в функцию newState
и, как показано в приведенном ниже коде, но, к сожалению, возвращает все состояние (а не его фрагмент).
О, и мы, должно быть, убедились, что подписались на mainStore
в viewDidLoad()
здесь через mainStore
вызов mainStore.subscribe(self)
, который связывает контроллер представления с mainStore
.
Вывод
Следующим этапом этого будет добавление промежуточного программного обеспечения, которое обеспечивает точку расширения между отправкой действия и достижением этого действия редуктора, который затем заставит нас задуматься о redux-thunk. Проще говоря, редукторы здесь должны быть чистыми функциями (без побочных эффектов), что означает, что вызовы API не могут выполняться внутри редуктора - это становится немного сложнее и, следовательно, потребуется сама статья!
Оглядываясь назад на эту статью, мы видим, что ReSwift (пока) не выполняет различие в состоянии - поэтому просто возвращает newState при изменении состояния, что означает, что (в этой конкретной реализации) это должно быть обработано в представлении, что-то, что явно было бы не лучшим.
Могу ли я использовать ReSwift в рабочем приложении? Что ж, SwiftUI может быть наиболее продуктивным способом управления состоянием и достижения прогресса в этой области, а не поиск решений в Интернете или Android.
Ой. Хотите репо с примером проекта. Считайте это сделанным ».
Если у вас есть вопросы, комментарии или предложения, пишите мне в Twitter.
Не стесняйтесь подписаться на мою рассылку новостей