Многие разработчики привыкли вызывать API прямо в .onAppear. Вроде логично: экран показался - пора грузить данные. В маленьких проектах это работает. Но когда приложение растет, начинаются проблемы: дублирующиеся запросы, утечки памяти, неправильное состояние интерфейса. Давайте разберемся, почему .onAppear - это ловушка и как правильно выполнять загрузку данных с помощью .task и конечного автомата.
В чем проблема .onAppear:
В SwiftUI вью - это легковесные структуры. Они создаются и пересоздаются постоянно. .onAppear срабатывает каждый раз, когда представление становится видимым. Если пользователь открыл экран, вернулся назад и снова зашел - запрос улетит повторно, хотя данные уже есть.
Еще хуже с отменой задач. Когда вы пишете Task { await loadData() } внутри .onAppear, вы создаете неструктурированную задачу. Если пользователь закрыл экран до завершения запроса, задача продолжает висеть в памяти. Результат - утечки, лишний трафик, проблемы с батареей.
Можно добавить ручную отмену в .onDisappear, но это лишний код, который легко забыть. А еще классическая проблема - куча флагов isLoading, error, data. Они независимы, и интерфейс может перейти в противоречивое состояние: например, одновременно крутится лоадер и показывается ошибка.
Что использовать вместо этого:
Вместо трюков с флагами нужно ввести конечный автомат - перечисление, которое описывает все возможные состояния экрана:
🔹.idle - еще ничего не началось.
🔹.loading - идет загрузка.
🔹.loaded(User) - данные получены.
🔹.error(Error) - произошла ошибка.
Это гарантирует, что в каждый момент времени экран может находиться только в одном состоянии. Никакой путаницы. Бизнес-логику выносим в отдельную ViewModel (класс с
@Observable). В ней один метод, который меняет состояние.Почему .task лучше:
В представлении вместо .onAppear используем модификатор .task потому что он:
🔹Работает с async/await из коробки - не нужно вкладывать задачу в Task { }.
🔹Автоматически отменяет запрос, если представление было удалено из иерархии.
🔹Не требует ручной отмены в .onDisappear.
🔗 Читать подробнее
💡 Вывод:
.onAppear - это не инструмент для загрузки данных. Это событие жизненного цикла. Используя его для API, вы боретесь с фреймворком: вручную управляете отменой задач, плодите невозможные состояния и рискуете утечками. Правильный подход - конечный автомат на перечислениях и модификатор .task, который берет на себя управление жизненным циклом. Код становится чище, а компилятор сам следит за тем, чтобы вы обработали все состояния.
Подписаться на канал:
➡️ Telegram | Max
Закрытый канал:
🚀 Мобильный трудоголик PRO
