Özet - setState
- Flutter kursu
- Orta seviye
- Ders 5/99
- 4 dk
setState ve lifting pattern'ini birleştirerek sayaç ekranı yaparsın.
Özet - setState
Bu bölümde üç şey öğrendin: setState bir State'i dirty işaretler ve sonraki frame'de build'i yeniden çalıştırır; lifting state up ile state'i kardeşlerin ortak ebeveynine taşıyıp callbacklerle çocuklara iletirsin; mounted kontrolü ile async sonrası güvenli setState yaparsın.
if (mounted) {
setState(() { _sayac++; });
}State'i mümkün olduğunca küçük tut ve her async sonrası mounted'ı kontrol et.
Uygulama Sayaç ekranı: setState + lifting + mounted
SayacEkrani stateful widget'ında _sayac ve _durum tut. _artir ve _azalt metotları setState ile _sayac'ı değiştirsin. _durumYukle async metodu 100 ms bekleyip if (mounted) ile _durum'u 'hazır' yapsın. initState içinde print('başlangıç: $_sayac') çağır ve _durumYukle'yi başlat. Gosterici stateless widget'ı deger alsın.
Başlangıç kodu
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: SayacEkrani());
}
}
class SayacEkrani extends StatefulWidget {
@override
_SayacEkraniState createState() => _SayacEkraniState();
}
class _SayacEkraniState extends State<SayacEkrani> {
int _sayac = 0;
String _durum = 'bekliyor';
// _artir ve _azalt: setState ile _sayac'ı değiştir
// _durumYukle: async, mounted kontrolü, setState ile _durum='hazır'
@override
void initState() {
super.initState();
print('başlangıç: $_sayac');
_durumYukle();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Sayaç - $_durum')),
body: Center(child: Gosterici()),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _azalt,
child: Icon(Icons.remove),
),
SizedBox(width: 8),
FloatingActionButton(
onPressed: _artir,
child: Icon(Icons.add),
),
],
),
);
}
}
class Gosterici extends StatelessWidget {
// deger field ve constructor ekle
@override
Widget build(BuildContext context) {
return Text('$deger', style: TextStyle(fontSize: 48));
}
}Örnek çözüm
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: SayacEkrani());
}
}
class SayacEkrani extends StatefulWidget {
@override
_SayacEkraniState createState() => _SayacEkraniState();
}
class _SayacEkraniState extends State<SayacEkrani> {
int _sayac = 0;
String _durum = 'bekliyor';
Future<void> _durumYukle() async {
await Future.delayed(Duration(milliseconds: 100));
if (mounted) {
setState(() {
_durum = 'hazır';
});
}
}
void _artir() {
setState(() {
_sayac++;
});
}
void _azalt() {
setState(() {
_sayac--;
});
}
@override
void initState() {
super.initState();
print('başlangıç: $_sayac');
_durumYukle();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Sayaç - $_durum')),
body: Center(child: Gosterici(deger: _sayac)),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _azalt,
child: Icon(Icons.remove),
),
SizedBox(width: 8),
FloatingActionButton(
onPressed: _artir,
child: Icon(Icons.add),
),
],
),
);
}
}
class Gosterici extends StatelessWidget {
final int deger;
Gosterici({required this.deger});
@override
Widget build(BuildContext context) {
return Text('$deger', style: TextStyle(fontSize: 48));
}
}Beklenen çıktı
başlangıç: 0
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Async bir Future bekledikten sonra setState'i güvenli çağırmak için ne yapmalısın?
- Önce if (mounted) kontrolü yap Doğru cevap
- Önce dispose çağır
- Önce initState'i tekrar çağır
- Önce Future'i iptal et
Açıklama: Async sonrası widget dispose edilmiş olabilir; if (mounted) ile State'in hâlâ ağaçta olduğu doğrulanır, sonra setState çağrılır.
2 Çocuğun callback field'ını tanımla
class Dugme extends StatelessWidget {
final VoidCallback ____;
Dugme({required this.onTikla});
@override
Widget build(BuildContext context) => Text('Düğme');
}
class Dugme extends StatelessWidget {
final VoidCallback onTikla;
Dugme({required this.onTikla});
@override
Widget build(BuildContext context) => Text('Düğme');
}
Açıklama: Lifting deseninde çocuk, callback'i constructor parametresi olarak alır ve bir field'da tutar; ebeveyn setState ile state'i günceller.
3 setState bölümünün parçaları
| Kavram | Anlamı |
|---|---|
setState |
State değişikliğini framework'e bildirir |
mounted |
Async sonrası setState için güvenlik kontrolü |
Lifting state up |
Kardeşlerin ortak ebeveynine state taşır |
Callback |
Çocuğun ebeveyne olay bildirme yolu |