Flutter Lesson 7 of 83 2 min read
StatelessWidget in Flutter
Learn how to write a StatelessWidget in Flutter: the build method, constructor parameters, const constructors and when to use one.
On this page
A StatelessWidget has no data of its own that changes. What it shows depends only on the values passed to its constructor. Most widgets you write will be stateless.
The shape of a stateless widget #
import 'package:flutter/material.dart';
class Greeting extends StatelessWidget {
const Greeting({super.key, required this.name, this.excited = false});
final String name;
final bool excited;
@override
Widget build(BuildContext context) {
return Text(
excited ? 'Hello, $name!' : 'Hello, $name.',
style: const TextStyle(fontSize: 24),
);
}
}
void main() {
runApp(
const MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Greeting(name: 'Asha'),
Greeting(name: 'Bimal', excited: true),
],
),
),
),
),
);
}
The parts:
| Part | Purpose |
|---|---|
extends StatelessWidget | Makes the class a widget |
const Greeting({super.key, ...}) | A const constructor with named parameters. super.key passes the optional key to the parent class |
final fields | The configuration. They never change after creation |
build | Returns the widgets this one is made of |
Why const matters #
Mark the constructor const, and write const where you use the widget whenever all its arguments are constants. Flutter can then reuse the same instance and skip rebuilding it. The linter reminds you when you forget.
const Greeting(name: 'Asha') // created once, reused
Greeting(name: userName) // not const: userName is only known at run time
Passing callbacks #
A stateless widget cannot change itself, but it can tell its parent that something happened by calling a function it was given.
import 'package:flutter/material.dart';
class QuantityButton extends StatelessWidget {
const QuantityButton({super.key, required this.label, required this.onPressed});
final String label;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return OutlinedButton(onPressed: onPressed, child: Text(label));
}
}
VoidCallback is the type of a function with no parameters and no result. For a callback that passes a value, use ValueChanged<T>, for example ValueChanged<int> onChanged.
When does build run? #
- When the widget first appears.
- When its parent rebuilds and passes new values.
- When something it depends on changes, such as the theme.
build can run many times a second, so keep it fast. Do not start network requests or heavy calculations inside it.
Stateless or stateful? #
Ask: does this widget need to remember something that changes while it is on screen?
- No:
StatelessWidget. A label, an avatar, a card that displays a product. - Yes:
StatefulWidget. A checkbox, a form, an animation.
Start stateless. Converting later is one editor action.
Try it yourself #
Write a StatusBadge widget that takes a label and an isActive flag. Show the label in green when active and grey when not.