Diff btw stateless and stateful widget and explain
#widget#state
Answer
Overview
StatelessWidget and StatefulWidget are the two fundamental widget types in Flutter. The key difference is that StatefulWidget can change over time (mutable state), while StatelessWidget cannot (immutable).
Comparison Table
| Feature | StatelessWidget | StatefulWidget |
|---|---|---|
| State | Immutable (cannot change) | Mutable (can change) |
| Rebuild | Only when parent rebuilds | Can rebuild with setState() |
| Lifecycle | Simple (build() only) | Complex (multiple methods) |
| Performance | Faster (less overhead) | Slightly slower |
| Memory | Less memory | More memory (State object) |
| Use Case | Static UI | Dynamic/Interactive UI |
| Examples | Text, Icon, Image | Checkbox, TextField, Animations |
StatelessWidget
Definition
A widget that never changes once built. Immutable configuration.
Structure
dartclass WelcomeScreen extends StatelessWidget { final String userName; const WelcomeScreen({required this.userName}); Widget build(BuildContext context) { return Text('Welcome, $userName!'); } }
Characteristics
- Single method: Only build()
- Cannot change: Properties are final
- Lightweight: No State object
- Performance: Efficient for static content
When to Use
- Static text/images
- Layout containers
- Icons and styling
- Content that doesn't change
Example
dartclass ProfileCard extends StatelessWidget { final String name; final String email; final String avatarUrl; const ProfileCard({ required this.name, required this.email, required this.avatarUrl, }); Widget build(BuildContext context) { return Card( child: Column( children: [ CircleAvatar(backgroundImage: NetworkImage(avatarUrl)), Text(name, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), Text(email, style: TextStyle(color: Colors.grey)), ], ), ); } }
StatefulWidget
Definition
A widget that can change over time. Has mutable state managed by a State object.
Structure
dartclass CounterScreen extends StatefulWidget { _CounterScreenState createState() => _CounterScreenState(); } class _CounterScreenState extends State<CounterScreen> { int _counter = 0; // Mutable state void _increment() { setState(() { _counter++; }); } Widget build(BuildContext context) { return Column( children: [ Text('Count: $_counter'), ElevatedButton( onPressed: _increment, child: Text('Increment'), ), ], ); } }
Characteristics
- Two classes: Widget + State
- Mutable state: Can change via setState()
- Lifecycle methods: initState(), dispose(), etc.
- Heavier: More memory and overhead
When to Use
- Forms and input fields
- Animations
- Data fetching/loading states
- Interactive elements (buttons, checkboxes)
- Anything that changes over time
Example
dartclass LoginForm extends StatefulWidget { _LoginFormState createState() => _LoginFormState(); } class _LoginFormState extends State<LoginForm> { final _formKey = GlobalKey<FormState>(); String _email = ''; String _password = ''; bool _isLoading = false; Future<void> _login() async { if (_formKey.currentState!.validate()) { setState(() => _isLoading = true); // Simulate API call await Future.delayed(Duration(seconds: 2)); setState(() => _isLoading = false); } } Widget build(BuildContext context) { return Form( key: _formKey, child: Column( children: [ TextFormField( decoration: InputDecoration(labelText: 'Email'), onChanged: (value) => _email = value, ), TextFormField( decoration: InputDecoration(labelText: 'Password'), obscureText: true, onChanged: (value) => _password = value, ), _isLoading ? CircularProgressIndicator() : ElevatedButton( onPressed: _login, child: Text('Login'), ), ], ), ); } }
Key Differences Explained
1. State Management
StatelessWidget:
dart// Cannot change this value final String title = 'Hello';
StatefulWidget:
dart// Can change via setState() String title = 'Hello'; void updateTitle() { setState(() { title = 'Goodbye'; }); }
2. Rebuild Mechanism
StatelessWidget: Rebuilds only when parent rebuilds
StatefulWidget: Rebuilds when:
- Parent rebuilds
- setState() is called
- Dependencies change
3. Memory Footprint
StatelessWidget:
- Single object (widget)
- ~100 bytes
StatefulWidget:
- Two objects (widget + state)
- ~200-300 bytes
When to Choose Which
Choose StatelessWidget If:
- ✅ Data is static
- ✅ No user interaction
- ✅ No animations
- ✅ Display-only content
- ✅ Performance is critical
Choose StatefulWidget If:
- ✅ Data changes over time
- ✅ User input/interaction
- ✅ Animations
- ✅ API calls/async operations
- ✅ Form handling
Best Practices
Rule of Thumb: Start with StatelessWidget. Convert to StatefulWidget only when needed.
dart// ✅ Good - Use StatelessWidget for static content class AppTitle extends StatelessWidget { Widget build(BuildContext context) { return Text('My App'); } } // ❌ Bad - Unnecessary StatefulWidget class AppTitle extends StatefulWidget { ... } // ✅ Good - Use const for better performance class AppTitle extends StatelessWidget { const AppTitle(); Widget build(BuildContext context) { return const Text('My App'); } }
Common Pitfalls
❌ Using StatefulWidget unnecessarily
dart// Bad - No state changes class DisplayText extends StatefulWidget { ... }
✅ Use StatelessWidget instead
dart// Good class DisplayText extends StatelessWidget { ... }
❌ Forgetting setState()
dart// Bad - UI won't update void increment() { counter++; // Missing setState()! }
✅ Always use setState()
dart// Good void increment() { setState(() { counter++; }); }