A StatefulWidget lets your app remember and change information while it runs. It helps your app update the screen when something changes.
StatefulWidget in Flutter
class MyWidget extends StatefulWidget { @override State<MyWidget> createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { @override Widget build(BuildContext context) { return Container(); } }
The StatefulWidget class is immutable, but it creates a separate State object that holds mutable data.
The createState() method connects the widget to its state.
class Counter extends StatefulWidget { @override State<Counter> createState() => _CounterState(); } class _CounterState extends State<Counter> { int count = 0; @override Widget build(BuildContext context) { return Text('Count: $count'); } }
class ToggleText extends StatefulWidget { @override State<ToggleText> createState() => _ToggleTextState(); } class _ToggleTextState extends State<ToggleText> { bool showHello = true; @override Widget build(BuildContext context) { return Text(showHello ? 'Hello' : 'Goodbye'); } }
This app shows a button that counts how many times you press it. Each press updates the number on the button.
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: Center( child: CounterButton(), ), ), ); } } class CounterButton extends StatefulWidget { const CounterButton({super.key}); @override State<CounterButton> createState() => _CounterButtonState(); } class _CounterButtonState extends State<CounterButton> { int _count = 0; void _increment() { setState(() { _count++; }); } @override Widget build(BuildContext context) { return ElevatedButton( onPressed: _increment, child: Text('Clicked $_count times'), ); } }
Always call setState() to tell Flutter to update the screen when your data changes.
Keep your state variables inside the State class, not the StatefulWidget class.
Use StatefulWidget only when you need to change the UI dynamically; otherwise, use StatelessWidget.
StatefulWidget helps your app remember and change data while running.
It has two parts: the widget itself and its state that holds changing data.
Use setState() inside the state to update the UI when data changes.
Practice
StatefulWidget in Flutter?Solution
Step 1: Understand StatefulWidget role
A StatefulWidget allows the UI to update when its data changes during app use.Step 2: Compare options
Only To create a widget that can change its appearance or data during runtime describes this dynamic behavior; others describe static or unrelated features.Final Answer:
To create a widget that can change its appearance or data during runtime -> Option AQuick Check:
StatefulWidget = dynamic UI [OK]
- Confusing StatefulWidget with StatelessWidget
- Thinking StatefulWidget is for styling only
- Believing StatefulWidget controls navigation
StatefulWidget class in Flutter?Solution
Step 1: Identify correct base class
A StatefulWidget must extend the StatefulWidget class to have mutable state.Step 2: Check options
Only class MyWidget extends StatefulWidget {} extends StatefulWidget; others extend unrelated or incorrect classes.Final Answer:
class MyWidget extends StatefulWidget {} -> Option AQuick Check:
StatefulWidget class extends StatefulWidget [OK]
- Using StatelessWidget instead of StatefulWidget
- Extending Widget directly (not allowed)
- Confusing BuildContext with widget class
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int count = 0;
void increment() {
setState(() {
count += 1;
});
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $count'),
ElevatedButton(onPressed: increment, child: Text('Add'))
],
);
}
}Solution
Step 1: Understand setState usage
The increment method calls setState to update count and rebuild UI.Step 2: Predict UI update
After pressing the button once, count increases from 0 to 1, so text shows 'Count: 1'.Final Answer:
The text updates to 'Count: 1' after pressing the button once -> Option DQuick Check:
setState updates UI count = 1 [OK]
- Forgetting to call setState inside increment
- Assuming UI updates without setState
- Thinking button press does nothing
class MyWidget extends StatefulWidget {
@override
State<MyWidget> createState() {
return _MyWidgetState();
}
}
class _MyWidgetState extends State<MyWidget> {
int counter = 0;
void increment() {
counter += 1;
}
@override
Widget build(BuildContext context) {
return Text('Counter: $counter');
}
}Solution
Step 1: Check state update method
The increment method changes counter but does not call setState, so UI won't rebuild.Step 2: Verify other options
Override annotation is optional but recommended; private state class is normal; Text can display strings with variables.Final Answer:
increment method does not call setState, so UI won't update -> Option BQuick Check:
setState missing = no UI update [OK]
- Forgetting setState in state-changing methods
- Thinking private state class is an error
- Confusing override annotation necessity
StatefulWidget that increments the count only if the current count is even. Which modification to the increment method below achieves this?
void increment() {
setState(() {
count += 1;
});
}Solution
Step 1: Understand setState usage
setState must wrap the code that changes the state to update UI correctly.Step 2: Apply condition inside setState
Add an if check inside setState: if (count % 2 == 0) count += 1; correctly checks if count is even inside setState before incrementing.Step 3: Analyze other options
Move setState call outside the if: if (count % 2 == 0) { count += 1; } setState(() {}); calls setState after increment, which may update UI unnecessarily; Call setState only when count is odd: if (count % 2 != 0) setState(() { count += 1; }); increments only if odd, wrong logic; Remove setState and just increment count directly removes setState, so UI won't update.Final Answer:
Add an if check inside setState: if (count % 2 == 0) count += 1; -> Option CQuick Check:
Condition inside setState updates UI correctly [OK]
- Calling setState without changing state inside
- Changing state outside setState
- Wrong condition logic for even check
Ready to prove it?
Pass the test and this pattern moves unknown
