Efek dan Dependensi
Tangani efek samping dan injeksikan dependensi.
Efek dan Dependensi adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 4 pelajaran total.
Mengapa Efek Ada
Reducer harus tetap murni: dengan State dan Action tertentu, Reducer hanya mengubah keadaan. Namun, aplikasi nyata memerlukan efek samping seperti permintaan jaringan dan pewaktu. TCA memodelkannya sebagai efek yang dikembalikan Reducer, sehingga perubahan tetap murni sementara pekerjaan asinkron berjalan secara terpisah.
Pemisahan inilah yang membuat fitur dapat diuji.
import ComposableArchitecture
// Reducer stays pure; side effects are values it returns.
// Returning .none means no further work.Mengembalikan .none
Jika sebuah tindakan hanya mengubah keadaan dan tidak memerlukan pekerjaan lanjutan, Reducer mengembalikan .none. Inilah efek yang paling umum dan menandakan bahwa tidak ada pekerjaan asinkron yang perlu dilakukan.
Anda sudah melihatnya; ini adalah dasar yang menjadi pilihan cadangan setiap cabang.
import ComposableArchitecture
Reduce { state, action in
switch action {
case .incrementTapped:
state.count += 1
return .none
}
}Effect.run untuk Pekerjaan Asinkron
Untuk melakukan pekerjaan asinkron, Anda mengembalikan .run. Fungsi penutupnya menerima penangan send yang Anda gunakan untuk memasukkan hasil kembali ke sistem sebagai tindakan baru.
Di sini, tindakan fetch memuat data dan mengirimkan tindakan respons setelah selesai.
import ComposableArchitecture
Reduce { state, action in
switch action {
case .reloadTapped:
return .run { send in
let value = try await loadNumber()
await send(.responseReceived(value))
}
case let .responseReceived(value):
state.count = value
return .none
}
}Mengembalikan Hasil sebagai Action
Efek tidak dapat mengubah keadaan secara langsung; efek mengirimkan tindakan melalui send. Reducer kemudian menangani tindakan tersebut dan memperbarui keadaan. Perulangan ini memastikan setiap perubahan tetap berada di dalam Reducer.
Jadi, respons jaringan menjadi tindakan respons yang disimpan oleh Reducer.
import ComposableArchitecture
.run { send in
let result = try await fetch()
await send(.dataLoaded(result))
}
// .dataLoaded is then handled by the reducer to set state.Menangani Galat dalam Efek
Pekerjaan asinkron dapat menghasilkan galat. Anda dapat menangkap galat di dalam efek dan mengirimkan tindakan kegagalan, sehingga Reducer dapat berpindah ke keadaan galat dengan rapi.
Fungsi penutup catch opsional pada .run menerima galat yang dilemparkan.
import ComposableArchitecture
.run { send in
let value = try await loadNumber()
await send(.responseReceived(value))
} catch: { error, send in
await send(.loadFailed)
}Mengapa Dependensi Penting
Jika Reducer memanggil klien jaringan atau membaca tanggal secara langsung, Reducer menjadi sulit diuji dan dikendalikan. TCA mengatasinya dengan dependensi: layanan yang dapat disuntikkan dan diakses Reducer melalui @Dependency.
Dalam pengujian, Anda menggantinya dengan tiruan yang hasilnya dapat diprediksi.
import ComposableArchitecture
// Instead of calling APIClient.shared directly,
// inject it as a dependency so tests can replace it.Pembungkus Properti @Dependency
Di dalam Reducer, Anda mendeklarasikan dependensi dengan @Dependency dan menamainya berdasarkan jalur kuncinya dalam nilai dependensi. Pustaka menyediakan komponen bawaan seperti jam dan penghasil UUID.
Di sini, Reducer mengambil jam kontinu.
import ComposableArchitecture
@Reducer
struct TimerFeature {
@ObservableState
struct State: Equatable { var seconds = 0 }
enum Action { case start, tick }
@Dependency(\.continuousClock) var clock
var body: some ReducerOf<Self> {
Reduce { state, action in .none }
}
}Menggunakan Dependensi dalam Efek
Setelah dideklarasikan, Anda menggunakan dependensi tersebut di dalam .run. Karena jam disuntikkan, pengujian dapat menyediakan jam pengujian yang memajukan waktu sesuai kebutuhan.
Di sini, timer berdetak setiap detik menggunakan jam yang disuntikkan.
import ComposableArchitecture
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .start:
return .run { send in
for await _ in self.clock.timer(interval: .seconds(1)) {
await send(.tick)
}
}
case .tick:
state.seconds += 1
return .none
}
}
}Mendefinisikan Dependensi Sendiri
Anda mendaftarkan dependensi khusus dengan membuat suatu nilai memenuhi DependencyKey dan menyediakan liveValue. Kemudian, Anda menambahkan properti terhitung ke DependencyValues agar dependensi tersebut memiliki jalur kunci.
Di sini, klien API menjadi dependensi utama.
import ComposableArchitecture
struct NumberClient {
var fetch: () async throws -> Int
}
extension NumberClient: DependencyKey {
static let liveValue = NumberClient {
try await loadNumber()
}
}
extension DependencyValues {
var numberClient: NumberClient {
get { self[NumberClient.self] }
set { self[NumberClient.self] = newValue }
}
}Menyuntikkan Dependensi Khusus
Setelah jalur kunci tersedia, Reducer mendeklarasikan klien dengan @Dependency(\.numberClient) dan memanggilnya di dalam efek. Produksi menggunakan nilai aktif; pengujian menggantinya.
Di sini, tindakan muat ulang mengambil data melalui klien yang disuntikkan.
import ComposableArchitecture
@Reducer
struct NumberFeature {
@ObservableState
struct State: Equatable { var value = 0 }
enum Action { case reload, response(Int) }
@Dependency(\.numberClient) var numberClient
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .reload:
return .run { send in
let n = try await numberClient.fetch()
await send(.response(n))
}
case let .response(n):
state.value = n
return .none
}
}
}
}Membatalkan Efek
Efek yang berjalan lama seperti pengatur waktu harus dapat dibatalkan. Anda menandai efek dengan ID cancellable dan membatalkannya nanti dari tindakan lain dengan .cancel.
Di sini, pengatur waktu dapat dihentikan sesuai kebutuhan.
import ComposableArchitecture
enum CancelID { case timer }
// Start a cancellable effect:
.run { send in /* ... */ }
.cancellable(id: CancelID.timer)
// Stop it from another action:
.cancel(id: CancelID.timer)Pemeriksaan Singkat: Efek dan Hasil
Ingat kembali cara efek mengirimkan hasilnya kepada pereduksi.
Ringkasan: Efek dan Dependensi
Anda telah mempelajari cara TCA menangani efek samping dan injeksi:
- Pereduksi tetap murni dan mengembalikan nilai
Effect;.noneberarti tidak ada pekerjaan. .runmenjalankan pekerjaan asinkron dan mengirimkan hasilnya kembali melaluiawait send(.action).- Kesalahan ditangani dengan blok
catchmilik efek. @Dependencymenyuntikkan layanan seperti jam atau klien Anda sendiri, yang dideklarasikan melaluiDependencyKeydanDependencyValues.- Efek yang berjalan lama dapat dibuat
cancellableberdasarkan ID.
Selanjutnya, Anda akan menyusun fitur-fitur bersama dan mengujinya secara menyeluruh.
import ComposableArchitecture
// Recap: pure reducer + Effect.run for async work
// + @Dependency for testable, injectable services.Belajar Swift dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 122
- Pelajaran
- 409
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Efek dan Dependensi” gratis?
Ya — teks lengkap “Efek dan Dependensi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Efek dan Dependensi”?
Tangani efek samping dan injeksikan dependensi. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Swift Academy?
Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Efek dan Dependensi” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?
Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.