Difference Between Stateless and Stateful Widgets in Flutter
In Flutter, widgets are the building blocks of the user interface. They are categorized into two types:
1. StatelessWidget
-
StatelessWidget does not change its state during its lifetime.
-
It is immutable, meaning its properties (data) cannot be changed after the widget is created.
-
Used for static UI components, like text, images, or buttons, where the content remains the same.
Example of StatelessWidget
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Stateless Example")),
body: const Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text(
"I am a StatelessWidget",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
);
}
}
Output:
The text "I am a StatelessWidget" is displayed. It does not change during the app's lifecycle.
2. StatefulWidget
-
StatefulWidget can change its state during its lifetime.
-
It is mutable, meaning it can hold and update data.
-
Used for interactive or dynamic UI components, like buttons, sliders, text fields, and counters.
Example of StatefulWidget
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text("Stateful Example")),
body: const Center(
child: MyStatefulWidget(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _counter = 0; // Variable that holds the state
void _incrementCounter() {
setState(() {
_counter++; // Update the state
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Counter: $_counter",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
ElevatedButton(
onPressed: _incrementCounter,
child: const Text("Increment Counter"),
),
],
);
}
}
Output:
-
The app shows "Counter: 0" initially.
-
Every time you press the "Increment Counter" button, the counter value increases by 1, and the UI updates.
Key Differences Summary
Feature | StatelessWidget | StatefulWidget |
---|---|---|
State | Cannot change (immutable). | Can change (mutable). |
Usage | Static or fixed content. | Dynamic or interactive content. |
Performance | More efficient as it does not rebuild. | Less efficient; rebuilds on state changes. |
Example | Displaying text, images, or icons. | Counter, toggle buttons, sliders. |
When to Use Which?
-
Use StatelessWidget if the UI does not need to change.
-
Use StatefulWidget if the UI needs to update based on user interaction or data changes.