State: apa itu, manajemen status dan prinsip kerja

Penulis: IT Sectr Diterbitkan: 2026-07-01 Waktu membaca: 9 mnt

State — objek pusat manajemen data di Flutter, yang terkait dengan StatefulWidget dan bertanggung jawab untuk menyimpan informasi yang dapat diubah dan membangun antarmuka. Menurut dokumentasi resmi Flutter (Flutter.dev, 2026), State ada sepanjang siklus hidup widget dan bertahan dari pembangunan ulangnya, memastikan konsistensi data antara pembaruan UI. Tidak seperti widget itu sendiri, State dapat mengubah bidangnya dan memulai pembangunan ulang melalui panggilan setState.

Poin Penting

  • State — objek yang menyimpan data yang dapat diubah dari StatefulWidget dan mengelola pembangunan ulangnya melalui setState
  • Siklus hidup — State melalui initState, didChangeDependencies, build, didUpdateWidget dan dispose, setiap tahap dengan tujuan yang jelas
  • mounted — bendera yang menunjukkan bahwa State masih berada di pohon widget dan dapat memanggil setState dengan aman
  • widget — referensi ke StatefulWidget terkait, dapat diakses melalui properti State untuk membaca parameter induk
  • Isolasi — State terisolasi dari State lainnya; untuk pertukaran data digunakan InheritedWidget atau alat manajemen status eksternal

Apa itu State di Flutter?

State — adalah objek dalam arsitektur Flutter yang menyimpan data yang dapat diubah dari StatefulWidget dan menentukan bagaimana data tersebut ditampilkan di antarmuka. Setiap StatefulWidget saat ditanamkan ke pohon membuat tepat satu objek State melalui metode createState. State ada secara independen dari widget: jika induk membangun ulang StatefulWidget dengan parameter baru, State tetap sama dan menerima widget yang diperbarui melalui properti widget.

Menurut Flutter Architectural Overview (Google, 2026), pemisahan Widget dan State adalah keputusan arsitektural yang disengaja yang memungkinkan framework menggunakan kembali elemen pohon. Widget (deskripsi ringan) dapat dibuat dan dihancurkan berkali-kali, tetapi State (objek berat dengan data) tetap di memori selama elemen berada di pohon. Ini mencegah kehilangan data saat sering terjadi pembangunan ulang widget induk.

State mengimplementasikan antarmuka StatefulWidget melalui generik: class _MyState extends State<MyWidget>. Generik mengikat State dengan tipe StatefulWidget tertentu, menyediakan akses aman-tipe ke bidangnya melalui properti widget.

Di mana State disimpan?

Objek State disimpan di StatefulElement — lapisan perantara antara Widget dan RenderObject. StatefulElement membuat State melalui createState, menyimpan referensi ke sana dan memberikan State sebagai pemilik. Elemen dihancurkan hanya ketika widget dihapus dari pohon — hingga saat itu State hidup di memori.

Siklus Hidup State

Siklus hidup State bersifat deterministik dan terdiri dari urutan panggilan yang ketat. Memahami urutan ini adalah dasar untuk bekerja dengan benar dengan sumber daya dan mencegah kebocoran memori.

initState — inisialisasi

initState dipanggil pertama saat pembuatan State. Dalam metode ini, pengontrol, langganan aliran data, timer dan nilai awal bidang diinisialisasi. Memanggil super.initState() di baris pertama wajib dilakukan. Pada tahap initState, pohon widget belum sepenuhnya terpasang, sehingga metode seperti MediaQuery.of(context) mungkin tidak berfungsi dengan benar.

didChangeDependencies

didChangeDependencies dipanggil setelah initState dan setiap kali ketergantungan InheritedWidget berubah. Di sinilah, bukan di initState, MediaQuery.of(context) atau Theme.of(context) harus dipanggil, karena pada saat ini pohon sudah terpasang. Metode ini juga dipanggil jika widget dipindahkan ke konteks lain di mana InheritedWidget memberikan nilai yang berbeda.

build — membangun UI

build — metode utama State yang mengembalikan pohon widget. Dipanggil setelah initState, setelah didChangeDependencies dan setelah setiap setState. Metode build tidak boleh memiliki efek samping — ia hanya mendeskripsikan antarmuka berdasarkan nilai bidang State saat ini.

didUpdateWidget

didUpdateWidget dipanggil ketika induk membangun ulang StatefulWidget dengan parameter baru. State mendapatkan akses ke widget lama melalui oldWidget dan dapat membandingkannya dengan yang baru. Jika parameter berubah, status dapat diperbarui, data baru dimuat, atau animasi dapat dimulai ulang.

dispose — membebaskan sumber daya

dispose — metode akhir di mana semua sumber daya dibebaskan: pengontrol, langganan, timer. Setelah dispose, State ditandai sebagai mati: mounted mengembalikan false, panggilan setState memicu pengecualian. Memanggil super.dispose() di baris terakhir metode wajib dilakukan.

MetodeKapan dipanggilsuper wajib
initStateSaat pembuatan StateYa, di baris pertama
didChangeDependenciesSetelah initState dan saat InheritedWidget berubahYa
buildSetelah initState, didChangeDependencies, setStateTidak
didUpdateWidgetSaat widget baru dari indukYa
setStateSaat dipanggil oleh pengembangTidak
disposeSaat dihapus dari pohonYa, di baris terakhir

Bagaimana State Bekerja?

Mekanisme kerja State didasarkan pada tiga prinsip utama: asosiasi dengan Element, reaktivitas melalui setState dan akses ke induk melalui properti widget. Ketika Flutter membangun pohon elemen dan menemukan StatefulElement, ia memanggil createState dari widget terkait. State yang dibuat disimpan dalam elemen dan ada sampai elemen tersebut dihapus.

Saat memanggil setState, State menandai dirinya sebagai “kotor” (dirty) dan menjadwalkan pembangunan ulang untuk bingkai berikutnya. Penting: setState tidak memanggil build segera — ia hanya mencatat perlunya pembangunan ulang. Flutter mengumpulkan semua elemen kotor dalam bingkai saat ini dan membangunnya ulang secara batch, yang mengoptimalkan kinerja. Setelah panggilan build, State kembali ke status “bersih” (clean).

Properti widget memungkinkan State membaca parameter yang diteruskan ke konstruktor StatefulWidget. Karena StatefulWidget tidak dapat diubah (seperti StatelessWidget), bidangnya tidak berubah — saat parameter berubah, induk membuat widget baru, dan State menerimanya melalui didUpdateWidget. Ini menjamin bahwa State selalu bekerja dengan data induk yang terkini.

Contoh Kode di Dart

Contoh dasar State dengan bidang yang diubah oleh timer. Mendemonstrasikan initState, setState dan dispose:

dart
class _TimerWidgetState extends State<TimerWidget> {
  int _seconds = 0;
  Timer? _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(
      const Duration(seconds: 1),
      (_) => setState(() => _seconds++),
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text('$_seconds detik telah berlalu');
  }
}

Contoh penggunaan properti widget untuk akses ke parameter induk dan reaksi terhadap perubahannya melalui didUpdateWidget:

dart
class _GreetingState extends State<GreetingWidget> {
  String _displayName = '';

  @override
  void initState() {
    super.initState();
    _displayName = _formatName(widget.name);
  }

  @override
  void didUpdateWidget(GreetingWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.name != oldWidget.name) {
      setState(() {
        _displayName = _formatName(widget.name);
      });
    }
  }

  String _formatName(String name) => name.trim().isEmpty ? 'Guest' : name;

  @override
  Widget build(BuildContext context) {
    return Text('Halo, $_displayName!');
  }
}

Dalam contoh kedua, State melacak perubahan parameter masukan name dan memformat ulang tampilan hanya saat terjadi perubahan nyata. Tanpa pemeriksaan widget.name != oldWidget.name, metode akan dipanggil pada setiap pembangunan ulang induk, bahkan jika nama tidak berubah — ini pekerjaan yang tidak perlu bagi framework.

State vs StatefulWidget

State dan StatefulWidget adalah dua kelas berbeda dalam arsitektur Flutter dengan peran yang berbeda. StatefulWidget — adalah pembungkus ringan yang tidak dapat diubah yang mendeskripsikan konfigurasi widget dan membuat State. State — adalah objek berat yang menyimpan data yang dapat diubah, mengelola langganan dan membangun UI. Pemisahan ini memungkinkan Flutter menghancurkan dan membuat widget tanpa kehilangan status.

Semua bidang StatefulWidget harus final dan diatur di konstruktor — mereka tidak berubah setelah pembuatan. State, sebaliknya, dapat mengubah bidangnya kapan saja, tetapi semua perubahan harus didahului dengan panggilan setState, agar Flutter mengetahui perlunya pembangunan ulang. Ini adalah perbedaan utama: StatefulWidget adalah “apa yang ditampilkan”, State — “bagaimana menampilkan dan data apa yang digunakan”.

Menurut Flutter source code analysis (Flutter SDK, 2026), StatefulWidget hanya berisi satu bidang wajib — createState, sementara State memiliki akses ke BuildContext, dapat berlangganan aliran, mengelola animasi dan pengontrol. Disarankan untuk menjaga StatefulWidget sesederhana mungkin, memindahkan semua logika ke State.

Mengapa StatefulWidget tidak bisa menjadi State?

Pemisahan Widget dan State — keputusan arsitektural yang menjamin kekekalan konfigurasi. Jika StatefulWidget sendiri menyimpan status, pada setiap pembangunan ulang induk status akan hilang. Dengan memisahkan status ke objek terpisah, Flutter menjamin bahwa data bertahan dari pembangunan ulang, dan widget tetap ringan dan dapat dibandingkan.

Manajemen Status Antar Widget

Objek State terisolasi — ia tidak memiliki akses langsung ke State widget lain. Untuk pertukaran data antar widget digunakan InheritedWidget atau alat manajemen status eksternal: Provider, Riverpod, Bloc, Redux. Setiap pendekatan memecahkan masalah dengan caranya sendiri: InheritedWidget bekerja melalui pohon widget, Provider — melalui kontainer DI, Bloc — melalui aliran peristiwa.

Pilihan alat tergantung pada skala proyek. Untuk aplikasi kecil, InheritedWidget dan State lokal sudah cukup. Untuk proyek menengah dan besar, direkomendasikan Riverpod atau Bloc — mereka memberikan kemampuan pengujian, prediktabilitas dan pemisahan logika dari UI. State dalam hal ini hanya digunakan untuk data lokal widget (fokus, gulir, animasi).

Menurut Flutter Community Survey 2025 (Flutter Foundation, Desember 2025), Riverpod adalah solusi paling populer untuk manajemen status di proyek baru (38%), diikuti oleh Bloc (31%) dan Provider (22%). Ketiga alat kompatibel dengan State dan tidak memerlukan pengabaian siklus hidup standar.

Status lokal vs global

  • Lokal — di State widget tertentu (posisi gulir, status fokus)
  • Global — di penyimpanan eksternal (data pengguna, pengaturan, cache)
  • Aturan: jika data hanya digunakan oleh satu widget — simpan di State
  • Jika data digunakan oleh 2+ widget — pindahkan ke Riverpod/Bloc/Provider

Kesalahan Umum

Kesalahan pertama — lupa memeriksa mounted sebelum setState di callback asinkron. Ketika widget telah dihapus dari pohon (misalnya, pengguna meninggalkan layar), tetapi operasi asinkron (permintaan HTTP) masih berjalan, setelah selesai State sudah mati. Memanggil setState di State yang mati memicu pengecualian. Pemeriksaan if (mounted) setState(...) memecahkan masalah.

Kesalahan kedua — inisialisasi ketergantungan InheritedWidget di initState alih-alih didChangeDependencies. Di initState konteks belum terpasang, sehingga MediaQuery.of(context) akan memicu pengecualian. Semua ketergantungan InheritedWidget harus dikonfigurasi di didChangeDependencies atau di build.

Kesalahan ketiga — mutasi bidang tanpa memanggil setState. Jika pengembang mengubah bidang State tanpa setState, Flutter tidak akan tahu tentang perubahan dan UI tidak akan diperbarui. Contoh: _list.add(item) tanpa setState((){}) berikutnya akan mengubah daftar, tetapi layar akan tetap sama.

Pemeriksaan mounted sebelum setState

Pola keamanan untuk operasi asinkron di State:

dart
Future<void> _fetchData() async {
  final data = await ApiService.fetch();
  if (mounted) {
    setState(() => _data = data);
  }
}

Pemeriksaan mounted menjamin bahwa setState hanya dipanggil untuk State yang hidup, mencegah pengecualian “setState called after dispose”.

Pertanyaan yang Sering Diajukan

Apa perbedaan State dengan StatefulWidget?

StatefulWidget — konfigurasi widget yang tidak dapat diubah, sedangkan State — objek yang dapat diubah yang menyimpan data dan mengelola siklus hidup. Widget dapat dibuat ulang, State — tidak. StatefulWidget membuat State melalui createState.

Berapa banyak objek State yang dibuat untuk satu StatefulWidget?

Tepat satu. Metode createState dipanggil sekali saat pertama kali StatefulWidget ditanamkan ke pohon. Bahkan jika induk membangun ulang berkali-kali, objek State tetap sama, sampai tipe atau Key widget berubah.

Apa itu mounted di State?

mounted — bendera boolean yang menunjukkan apakah State berada di pohon widget. Setelah memanggil dispose, mounted menjadi false. Digunakan untuk pemeriksaan sebelum setState di callback asinkron untuk menghindari pengecualian.

Bisakah State digunakan tanpa StatefulWidget?

Tidak. State selalu terikat ke StatefulWidget tertentu melalui generik: State<T extends StatefulWidget>. Membuat State secara langsung, tanpa asosiasi dengan widget, secara arsitektural tidak mungkin.

Apa yang terjadi jika setState dipanggil di dispose?

Akan memicu pengecualian: “setState called after dispose”. Setelah memanggil dispose, State dianggap mati dan setiap upaya untuk membangun ulang UI melalui setState dilarang. Solusi — periksa mounted sebelum setiap setState.

Ringkasan

  • State — objek manajemen data StatefulWidget, menyimpan bidang yang dapat diubah dan memulai pembangunan ulang UI melalui setState
  • Siklus hidup mencakup metode wajib initState, didChangeDependencies, build, didUpdateWidget dan dispose, masing-masing dengan tujuannya sendiri
  • mounted — bendera keamanan kritis yang mencegah panggilan setState setelah widget dihapus dari pohon
  • widget — properti State untuk akses ke parameter StatefulWidget terkait, diperbarui melalui didUpdateWidget
  • Isolasi — State tidak memiliki akses ke State lain; interaksi antar widget dilakukan melalui InheritedWidget atau alat eksternal
  • setState — tidak memanggil build segera, hanya menandai State sebagai kotor untuk pembangunan ulang di bingkai berikutnya
  • Aturan — gunakan State untuk data lokal widget; status global pindahkan ke lapisan eksternal (Riverpod, Bloc)

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.

Diskusikan proyek

Baca juga