Summary - setState
- Flutter course
- Intermediate
- Lesson 5/99
- 4 min
Combine setState and lifting to build a counter screen.
Summary - setState
In this section you learned three things: setState marks a State dirty and reruns build on the next frame; with lifting state up you move state to the common parent of siblings and pass callbacks to children; with the mounted check you safely call setState after async work.
if (mounted) {
setState(() { _count++; });
}Keep state as small as possible and check mounted after every async wait.
Practice Counter screen: setState + lifting + mounted
In the SayacEkrani stateful widget, hold _sayac and _durum. The _artir and _azalt methods should change _sayac with setState. The async _durumYukle method waits 100 ms and sets _durum to 'hazır' with if (mounted). In initState, call print('başlangıç: $_sayac') and start _durumYukle. The Gosterici stateless widget should take deger.
Starter code
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));
}
}Sample solution
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));
}
}Expected output
başlangıç: 0
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What should you do to safely call setState after awaiting a Future?
- Check if (mounted) first Correct answer
- Call dispose first
- Call initState again first
- Cancel the Future first
Explanation: After async the widget may have been disposed; if (mounted) verifies the State is still in the tree before calling setState.
2 Define the child's callback field
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');
}
Explanation: In the lifting pattern, the child receives the callback as a constructor parameter and stores it in a field; the parent updates state with setState.
3 setState section parts
| Term | Meaning |
|---|---|
setState |
Notifies the framework of state change |
mounted |
Safety check before setState after async |
Lifting state up |
Moves state to siblings' common parent |
Callback |
Child's way to report events to parent |