44
Flutter Stateful and Stateless widgets
Yesterday we had a high-level overview of how Flutter works, and learned it uses a widget approach.
Today we'll dive a little bit deeper into the two main types of widgets being:
The state, in general, is information about that widget that can be read once the widget is built. If this never changes, we consider it a stateless widget. If this information can change, it's a stateful widget.
Stateless widgets can never change. Some examples of stateless widgets are
Icon
, Text
, and IconButton
.A stateful widget is dynamic. It might change appearance based on user interaction of when data changes.
Some examples might are
Some examples might are
TextField
, Checkbox
, and Radio
.Let's showcase a basic stateless widget that will show some text but not do anything.
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return Center(
child: Text(
'Hello World 👋',
textDirection: TextDirection.ltr,
),
);
}
}
As you can see above, this widget is going to render some text inside a center element.
That's it. That fact won't change no matter what happens.
That's it. That fact won't change no matter what happens.
Stateful widgets are a different story. As mentioned, they might change properties based on data or user action.
Let's use the Flutter demo and create a basic application that will plus a counter when we click a button.
class MyApp extends StatefulWidget {
_MyAppState createState() => _MyAppState();
}
As you can see, we changed the
That means it must implement the
MyApp
to be a stateful widget now.That means it must implement the
createState
function, which in our case calls the _MyAppState
class.Note: The underscore classes in Dart are considered private!
This new class will extend our basic app state, meaning it can handle change.
class _MyAppState extends State<MyApp> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
),
TextButton(
onPressed: _incrementCounter,
child: const Text('Add number'),
),
]),
),
);
}
}
In there, we define a basic counter variable and set it to zero.
Then we create a function that can increment this number.
Then we create a function that can increment this number.
Be aware that
setState
is needed to make an actual change in a state.Then we override the widget to create our widget as we did before, but in this one, we get to use a variable text and include a button that will handle an
onPressed
event.So what happens:
And this keeps looping on every interaction.
I hope you got a good overview of the difference between stateless and stateful widgets and how they come together in Flutter.
You can find my implementation of the Stateful widget on GitHub.