Materi
Di dalam State, data yang berubah disimpan sebagai field biasa, misalnya int _sisa = 12. Mengubah field itu saja tidak mengubah layar. setState(() { _sisa--; }) mengubah nilainya sekaligus memberi tahu Flutter bahwa State ini perlu dibangun ulang, lalu framework memanggil build lagi dan tampilan mengikuti nilai baru. Tanpa setState, build tidak dipanggil ulang, dan seolah tidak terjadi apa-apa.
class _StokState extends State<Stok> {
int _sisa = 12;
late final TextEditingController _catatan;
@override
void initState() {
super.initState(); // selalu di baris pertama
_catatan = TextEditingController();
}
@override
void dispose() {
_catatan.dispose(); // bersihkan sebelum State dibuang
super.dispose(); // di baris terakhir
}
@override
Widget build(BuildContext context) {
return Column(children: [
Text('Sisa: $_sisa'),
TextField(controller: _catatan),
ElevatedButton(
onPressed: () => setState(() => _sisa--),
child: const Text('Jual satu'),
),
]);
}
}Siklus hidup State berjalan begini. Setelah createState, Flutter memasukkan State ke pohon dan memanggil initState tepat sekali. Di sanalah controller, langganan, atau Future yang cukup dibuat sekali disiapkan, diawali super.initState(). build bisa dipanggil berkali-kali, setiap setState dan kapan pun framework membutuhkannya, jadi build tidak boleh mengirim permintaan jaringan. Saat State tidak lagi dibutuhkan, Flutter memanggil dispose untuk membersihkan controller dan timer, diakhiri super.dispose().
Jadi urutannya: createState, initState, build pertama, build lagi setiap ada setState, lalu dispose. Pembagian tugas ini membuat build tetap ringan: build hanya membaca field State dan menyusun widget, initState menyiapkan, dan dispose membersihkan.