CodeBlanks Logo Icon CodeBlanks

setState derinlemesine

setState'in nasıl çalıştığını ve ne zaman rebuild edeceğini öğrenirsin.

setState derinlemesine

setState bir State nesnesini 'dirty' (kirli) olarak işaretler ve framework'e bu widget'ı yeniden inşa etmesi gerektiğini söyler. Yeniden inşa hemen olmaz; framework bir sonraki frame'e kadar bu işi erteler.

void artir() {
  setState(() {
    sayac++;
  });
}

Bu sayede arka arkaya yapılan setState çağrıları tek bir rebuild'de birleştirilebilir.

scheduleBuild ve dirty

Aslında setState iki şey yapar: önce verdiğin callback'i çalıştırır (ör. sayac++), sonra State nesnesinin _dirty bayrağını true yapar ve markNeedsBuild çağrısı yapar. Bu çağrı elementi scheduler'ın listesine ekler.

setState(() { sayac++; });
// _dirty = true
// markNeedsBuild() planlandı

Sonraki frame başlayınca o element'in build metodu yeniden çağrılır.

Uygulama Sayaç artıran StatefulWidget

Bir StatefulWidget yap. _sayac değişkeni 0'dan başlasın. initState içinde print('başlangıç: $_sayac') çağır. Butona basıldığında setState ile _sayac'ı artır.

Başlangıç kodu

main.dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyCounter(),
    );
  }
}

class MyCounter extends StatefulWidget {
  @override
  _MyCounterState createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  int _sayac = 0;

  @override
  void initState() {
    super.initState();
    print('başlangıç: $_sayac');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Sayaç')),
      body: Center(
        child: Text('$_sayac'),
      ),
      floatingActionButton: FloatingActionButton(
        // setState ile _sayac'ı artır
        onPressed: () {},
        child: Icon(Icons.add),
      ),
    );
  }
}

Örnek çözüm

main.dart
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyCounter(),
    );
  }
}

class MyCounter extends StatefulWidget {
  @override
  _MyCounterState createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> {
  int _sayac = 0;

  @override
  void initState() {
    super.initState();
    print('başlangıç: $_sayac');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Sayaç')),
      body: Center(
        child: Text('$_sayac'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _sayac++;
          });
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

Beklenen çıktı

başlangıç: 0

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 setState çağrıldığında hangisi olur?

  • State dirty işaretlenir ve bir sonraki frame'de rebuild planlanır Doğru cevap
  • Uygulama yeniden başlatılır ve main tekrar çalışır
  • Yalnızca initState içinde geçerlidir, başka yerde hata fırlatır
  • build metodu hemen aynı call stack'te çalışır

Açıklama: setState State'i dirty işaretler ve markNeedsBuild ile bir sonraki frame'de rebuild planlar; build hemen senkron çağrılmaz.

2 setState çağrısını tamamla

Soru
void artir() {
  ____(() {
    sayac++;
  });
}
Cevap
void artir() {
  setState(() {
    sayac++;
  });
}

Açıklama: setState, verilen callback'i çalıştırdıktan sonra State'i dirty işaretler ve build'i planlar.

3 State yaşam döngüsü parçaları

Kavram Anlamı
setState State'i dirty işaretler ve build planlar
initState State oluşturulduğunda bir kez çağrılır
build Widget ağacını döndüren metod
dispose State yok edilirken çağrılır

Orta seviye bölümündeki tüm dersler