@State adalah Property Wrapper di SwiftUI untuk mengelola status lokal dalam satu tampilan. SwiftUI secara otomatis menggambar ulang tampilan setiap kali properti @State berubah, membuat antarmuka menjadi reaktif tanpa panggilan pembaruan manual. Menurut Apple Developer Documentation (2025), @State direkomendasikan untuk tipe sederhana dan struktur yang dimiliki oleh satu tampilan. @State adalah cara paling sederhana untuk menambahkan interaktivitas ke antarmuka SwiftUI.
Poin utama
@State adalah Property Wrapper bawaan di SwiftUI yang memungkinkan tampilan menyimpan dan melacak statusnya sendiri. Ketika nilai @State berubah, SwiftUI secara otomatis menggambar ulang tampilan dengan memanggil ulang properti body. Ini adalah dasar dari pemrograman reaktif di SwiftUI: pengembang mendeklarasikan status, dan framework menangani sinkronisasi antarmuka.
@State menciptakan area penyimpanan di heap yang dikelola oleh SwiftUI. Area ini persisten — ia bertahan dari inisialisasi berulang struktur tampilan yang terjadi setiap render. SwiftUI menggunakan pengidentifikasi tampilan (dihasilkan berdasarkan posisi dalam hierarki) untuk mengikat properti @State ke tampilan tertentu. Berkat ini, status tidak diatur ulang saat tampilan induk diperbarui.
Batasan penting: @State hanya ditujukan untuk tipe nilai (struktur, enumerasi, primitif). Untuk tipe referensi (kelas) gunakan @StateObject atau @ObservedObject. Jika Anda menetapkan kelas ke properti @State, SwiftUI tidak akan dapat mendeteksi perubahan di dalam objek — hanya penggantian seluruh referensi.
SwiftUI mengimplementasikan @State melalui mekanisme internal Storage. Setiap properti @State mendapatkan sel memori khusus yang disimpan dalam wadah penyimpanan khusus tampilan. Ketika penulisan ke wrappedValue terjadi, SwiftUI melalui didSet memberitahu grafik ketergantungannya (dependency graph) tentang perlunya penggambaran ulang.
struct ContentView: View {
@State private var name: String = "User"
@State private var isLoggedIn: Bool = false
var body: some View {
VStack {
Text("Halo, \(name)")
Button(isLoggedIn ? "Keluar" : "Masuk") {
isLoggedIn.toggle()
}
}
}
}
Dalam contoh ada dua properti @State: name (String) dan isLoggedIn (Bool). Saat isLoggedIn.toggle() dipanggil, SwiftUI menandai ContentView sebagai memerlukan pembaruan dan menjalankan ulang body di siklus render berikutnya. Poin kunci: properti @State selalu dideklarasikan dengan pengubah private — ini adalah sinyal bahwa status hanya milik tampilan saat ini dan tidak boleh diubah dari luar secara langsung.
Untuk mengamati perubahan, SwiftUI menggunakan CurrentValueSubject dari Combine. Setiap properti @State menciptakan penerbit tersembunyi yang memberi tahu sistem pada setiap perubahan. Ini memungkinkan SwiftUI untuk menggambar ulang hanya kumpulan tampilan yang minimal diperlukan, menghindari pembaruan penuh hierarki.
@State optimal untuk status lokal sederhana: bidang teks pencarian, bendera boolean untuk jendela modal, sakelar pengaturan, penghitung, elemen daftar yang dipilih. Jika nilai hanya digunakan dalam satu tampilan dan komponen bersarangnya (melalui @Binding), @State adalah pilihan yang tepat. Untuk status yang harus bertahan setelah tampilan ditutup (misalnya data formulir), @State juga cocok selama tampilan tetap dalam hierarki.
Jangan gunakan @State untuk status global aplikasi, menyimpan cache data jaringan atau objek yang digunakan di beberapa layar. Untuk tujuan ini gunakan @StateObject dan @EnvironmentObject. @State juga tidak cocok untuk menyimpan data dalam jumlah besar — setiap kali berubah, seluruh tampilan akan digambar ulang.
@Binding adalah jembatan antara @State di tampilan induk dan tampilan anak yang perlu mengubah status ini. Induk mendeklarasikan @State, dan komponen anak menerima Binding melalui proyeksi $. Perubahan Binding di tampilan anak secara otomatis memperbarui @State di induk — dan sebaliknya. Ini memastikan aliran data satu arah dengan kemungkinan umpan balik.
struct ParentView: View {
@State private var text: String = ""
var body: some View {
ChildView(text: $text)
}
}
struct ChildView: View {
@Binding var text: String
var body: some View {
TextField("Enter text", text: $text)
}
}
Dalam listing, ParentView memiliki @State text, dan ChildView menerima $text sebagai Binding. TextField di dalam ChildView terikat ke Binding ini melalui text: $text. Ketika pengguna mengetik di TextField, nilainya berubah di ChildView melalui Binding, yang menyebabkan pembaruan @State di ParentView. Kedua tampilan digambar ulang dengan nilai baru.
Kesalahan paling umum — menetapkan kelas ke properti @State. Jika Anda menulis @State var model = MyClass(), SwiftUI tidak akan dapat melacak perubahan properti di dalam kelas — hanya penggantian objek itu sendiri. Untuk kelas selalu gunakan @StateObject. Masalah umum kedua — mendeklarasikan @State tanpa pengubah private, yang melanggar prinsip enkapsulasi status.
Memberikan @State secara langsung ke tampilan anak tanpa $ — kesalahan umum lainnya. Jika Anda memberikan TextField(text: text) alih-alih TextField(text: $text), komponen anak akan menerima string biasa, bukan Binding. Perubahan teks di TextField tidak akan disinkronkan dengan @State induk. Selalu gunakan proyeksi $ untuk memberikan Binding.
Kesalahan ketiga — beberapa properti @State untuk data yang terkait. Jika beberapa nilai secara logis membentuk satu kesatuan (misalnya bidang formulir), gabungkan mereka menjadi satu struktur dengan satu @State. Ini menyederhanakan pemberian status ke tampilan anak dan mengurangi jumlah pemicu pembaruan terpisah.
@State digunakan di sebagian besar proyek SwiftUI untuk interaktivitas dasar. Mari kita lihat contoh formulir masuk, di mana @State mengelola bidang teks dan status pemuatan. Pola ini ditemukan di setiap aplikasi — dari catatan sederhana hingga solusi perusahaan yang kompleks.
struct LoginView: View {
@State private var email: String = ""
@State private var password: String = ""
@State private var isLoading: Bool = false
@State private var errorMessage: String?
var body: some View {
Form {
TextField("Email", text: $email)
SecureField("Password", text: $password)
Button("Masuk") {
login()
}.disabled(isLoading)
}
}
private func login() {
isLoading = true
// Lakukan permintaan jaringan
}
}
Dalam contoh ada empat properti @State: email dan password untuk bidang formulir, isLoading untuk indikasi pemuatan dan errorMessage untuk menampilkan kesalahan. Setiap properti secara mandiri mengelola bagian antarmukanya sendiri. Saat isLoading berubah, tombol secara otomatis diblokir melalui disabled(isLoading) — tanpa pembaruan UI manual.
Pertanyaan yang sering diajukan
@State dirancang untuk status lokal tampilan tertentu. Pengubah private memastikan bahwa komponen lain tidak dapat mengubahnya secara langsung, melanggar enkapsulasi. Untuk akses eksternal gunakan proyeksi $.
Ya, @State mendukung array dan kamus, karena ini adalah tipe nilai. Namun saat mengubah elemen array, SwiftUI menggambar ulang seluruh tampilan. Untuk daftar besar, lebih efisien menggunakan @StateObject dengan @Published.
@State bekerja dengan benar dengan tipe Optional. Saat menetapkan nil, SwiftUI mendeteksi perubahan dan menggambar ulang tampilan. Ini berguna untuk status seperti errorMessage: String?, di mana nil berarti tidak ada kesalahan.
@State mempertahankan nilai selama tampilan tetap dalam hierarki. Jika tampilan dihapus dari hierarki dan ditambahkan lagi, @State diinisialisasi ulang dengan nilai default. Untuk persistensi gunakan @AppStorage.
Ya, bungkus perubahan dalam withAnimation: withAnimation(.easeInOut) { isExpanded.toggle() }. SwiftUI menganimasikan transisi antara status lama dan baru antarmuka dengan jenis animasi yang ditentukan.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga