Lift State Up
Part of the State Management section of Coddy's Flutter journey. Lesson 4 of 27.
Tap the thumb on the phone: the number next to it goes up, but the top bar still says 0 likes. The button keeps its count in its own State, and nothing else can see it.
When two widgets need the same value, move it up to the closest widget that holds them both. This is called lifting state up. The page owns likes, and the button becomes a StatelessWidget that gets the value and a callback:
LikeButton(
likes: likes,
onLike: () {
setState(() {
likes++;
});
},
)Now there is one count in one place. The top bar, the button and the reset button all read and change that one value, so they can never disagree.
A quick test: if a value is shown or changed in two places, the widget that owns it must be above both of them.
Challenge
MediumMake the page the only owner of the likes:
- Turn
LikeButtoninto aStatelessWidgetwith two fields:likesand anonLikecallback. - The page passes its own
likes, and anonLikethat adds 1 insidesetState.
Then the top bar follows the button, and the refresh button resets both.
Try it yourself
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(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int likes = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('$likes likes'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: () {
setState(() {
likes = 0;
});
},
),
],
),
body: const Center(
child: LikeButton(),
),
);
}
}
class LikeButton extends StatefulWidget {
const LikeButton({super.key});
@override
State<LikeButton> createState() => _LikeButtonState();
}
class _LikeButtonState extends State<LikeButton> {
int likes = 0;
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.thumb_up),
iconSize: 40,
onPressed: () {
setState(() {
likes++;
});
},
),
Text('$likes', style: const TextStyle(fontSize: 32)),
],
);
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in State Management
1Lifting State Up
Pass State to a ChildPass a Callback to a ChildCallbacks That Send a ValueLift State UpPractice on your own: Online Flutter compiler