Flutter'da Build Sırasında State Değişikliği Neden Hata Verir

Flutter'da en sık karşılaşılan hatalardan biri, `build()` metodunun çalışması sırasında `setState()` çağrısı yapmaktır. Ekran güncellenirken aynı anda durumu değiştirmeye kalktığında Flutter "setState() called during build" hatası fırlatır.

Bunun nedeni basit: build metodunun görevi UI'ı çizmek. Eğer bu sırada state değişirse, Flutter hangi duruma göre ekranı çizecek bilemededir. Widget ağacı kararsız hale gelir, performans düşer ve hata oluşur.

Çoğu zaman veri yükleme işlemini `build()` içinde başlatırız:

2Widget build(BuildContext context) {
3// YANLIŞ: Burada API çağrısı yapıp setState çağırırsan hata alırsın
4fetchData().then((_) => setState(() {}));
5return Scaffold();
6}

Bu kod her `build()` çağrısında tekrar tetiklenir. Sonsuz döngü ve hata garantili.

Veri yükleme ve state değişikliği için `initState()` metodunu kullan. Bu metod widget oluşturulduğunda bir kez çalışır:

1class MyWidget extends StatefulWidget {
3State<MyWidget> createState() => _MyWidgetState();
4}
5
6class _MyWidgetState extends State<MyWidget> {
7String data = 'Yükleniyor...';
8
10void initState() {
11super.initState();
12// Burada güvenle setState çağırabilirsin
13fetchData().then((result) {
14setState(() {
15data = result;
16});
17});
18}
19
20Future<String> fetchData() async {
21await Future.delayed(Duration(seconds: 2));
22return 'Veri yüklendi!';
23}
24
26Widget build(BuildContext context) {
27return Scaffold(
28body: Center(child: Text(data)),
29);
30}
31}

Çıktı: İlk açılışta "Yükleniyor..." gösterilir, 2 saniye sonra "Veri yüklendi!" görünür. Hata yok.

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası

WidgetsBinding.instance.addPostFrameCallback kullan:

2void initState() {
3super.initState();
4WidgetsBinding.instance.addPostFrameCallback((_) {
5setState(() => data = 'Güncellendi');
6});
7}

Bu, build tamamlandıktan sonra state değişikliğini güvenle yapar.

FutureBuilder veya StreamBuilder tercih et, setState'e ihtiyaç kalmaz:

2Widget build(BuildContext context) {
3return FutureBuilder<String>(
4future: fetchData(),
5builder: (context, snapshot) {
6if (snapshot.connectionState == ConnectionState.waiting) {
7return Text('Yükleniyor...');
8}
9return Text(snapshot.data?? 'Hata');
10},
11);
12}

- build() içinde setState çağırma, hata garantisi.
- initState() kullan, veri yükleme için ideal.
- WidgetsBinding veya FutureBuilder, daha temiz alternatifler.

Widget lifecycle'ını anladığında, bu tür hatalardan kurtulursun.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz