Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

60%
+1 −0
Q&A What is lifting state up in Flutter?

This article has a good explanation of lifting state up in Flutter. Let's say for example that we have a BlueSquare widget that displays the number of times it has been tapped. Each click on the...

posted 11mo ago by tarhalda‭  ·  edited 11mo ago by tarhalda‭

Answer
#2: Post edited by user avatar tarhalda‭ · 2023-06-21T22:00:11Z (11 months ago)
Added link to original post by me on StackOverflow
  • [This article](https://medium.com/nerd-for-tech/lifting-state-up-and-callbacks-7a19d0bdbe53) has a good explanation of lifting state up in Flutter.
  • >Let's say for example that we have a `BlueSquare` widget that displays the number of times it has been tapped. Each click on the square automatically updates the text displayed with the updated total number of clicks on that square. Let's say then that we wanted to have a set of `BlueSquares` and all the `BlueSquares` in that set display the accumulated number of clicks the user has done.
  • This means the number of clicks is a state shared by all the `BlueSquare` objects.
  • (Grammar and some minor phrasing corrected in quote above.)
  • Instead of making `BlueSquare` a `StatefulWidget`, we make it a `StatelessWidget` and make its parent a `StatefulWidget`. The `StatefulWidget`, `BlueSquareParent`, keeps track of the number of clicks. It passes the number of clicks to the `BlueSquare` widget's constructor so that `BlueSquare` widget can display the current click count.
  • ```flutter
  • class BlueSquare extends StatelessWidget{
  • final int numClicks;
  • BlueSquare({
  • required this.numClicks
  • }) : super();
  • Widget build(BuildContext context){
  • Container(
  • color: Colors.blue,
  • height: 30,
  • width: 30
  • child: TextButton(
  • child: const Text("$numClicks")
  • )
  • );
  • }
  • }
  • class BlueSquareParent extends StatefulWidget {
  • BlueSquareParentState createState() => BlueSquareParentState();
  • }
  • class BlueSquareParentState extends State<BlueSquareParent>{
  • //Initialize the number of clicks to 0
  • int numClicksTotal = 0;
  • @override
  • Widget build(){
  • return Scaffold(
  • body: Column(
  • children: [
  • BlueSquare(numClicks: numClicksTotal),
  • BlueSquare(numClicks: numClicksTotal)
  • ]
  • )
  • );
  • }
  • }
  • ```
  • In the `BlueSquare` example, we need to return the number of clicks to the `BlueSquareParent` widget so it knows how many there are. We can do this by passing a callback method to the `BlueSquares` that will let them update the number of clicks in `BlueSquareParent`.
  • ```flutter
  • class BlueSquare extends StatelessWidget{
  • final int numClicks;
  • final Function callback;
  • BlueSquare({
  • required this.numClicks,
  • required this.callback
  • }) : super();
  • Widget build(BuildContext context){
  • Container(
  • color: Colors.blue,
  • onTap: (){
  • callback();
  • }
  • height: 30,
  • width: 30
  • child: TextButton(
  • child: const Text("$numClicks")
  • )
  • );
  • }
  • }
  • class BlueSquareParent extends StatefulWidget {
  • BlueSquareParentState createState() => BlueSquareParentState();
  • }
  • class BlueSquareParentState extends State<BlueSquareParent>{
  • //Initialize the number of clicks to 0
  • int numClicksTotal = 0;
  • @override
  • Widget build(){
  • return Scaffold(
  • body: Column(
  • children: [
  • BlueSquare(numClicks: numClicksTotal, callback: addClick),
  • BlueSquare(numClicks: numClicksTotal, callback: addClick)
  • ]
  • )
  • );
  • }
  • void addClick(){
  • setState((){
  • numClicksTotal++;
  • });
  • }
  • }
  • ```
  • (All code adapted from the examples in the article.)
  • Another example: [This YouTube tutorial](https://www.youtube.com/watch?v=ZqEouycRSzY&list=PLPo5vEiJO3Bigfo2wMYF5xtLjwXJqsPTz&index=7&t=3113s) shows how to lift up state for `TextFormFields` so that the values put into those fields are stored in a parent widget. The child widget (`RangeSelectorTextFormField`) has a `TextFormField` in it and receives a callback method just like the `BlueSquare` widget in the first example. When the text in the field is saved, the callback method is called. In the parent widget, we create a function that sets either the minimum value or the maximum value variable in the parent widget, depending on which text field we're creating, and pass that as the callback method for the `RangeSelectorTextFormField`. Then, when the text in the the `TextFormField` is saved, `RangeSelectorTextFormField` calls the callback method, which sets the associated variable in the parent widget.
  • [Flutter documentation](https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple) recommends using `Provider` instead of lifting up state this way if you're doing anything much more complicated than the example above.
  • [This article](https://medium.com/nerd-for-tech/lifting-state-up-and-callbacks-7a19d0bdbe53) has a good explanation of lifting state up in Flutter.
  • >Let's say for example that we have a `BlueSquare` widget that displays the number of times it has been tapped. Each click on the square automatically updates the text displayed with the updated total number of clicks on that square. Let's say then that we wanted to have a set of `BlueSquares` and all the `BlueSquares` in that set display the accumulated number of clicks the user has done.
  • This means the number of clicks is a state shared by all the `BlueSquare` objects.
  • (Grammar and some minor phrasing corrected in quote above.)
  • Instead of making `BlueSquare` a `StatefulWidget`, we make it a `StatelessWidget` and make its parent a `StatefulWidget`. The `StatefulWidget`, `BlueSquareParent`, keeps track of the number of clicks. It passes the number of clicks to the `BlueSquare` widget's constructor so that `BlueSquare` widget can display the current click count.
  • ```flutter
  • class BlueSquare extends StatelessWidget{
  • final int numClicks;
  • BlueSquare({
  • required this.numClicks
  • }) : super();
  • Widget build(BuildContext context){
  • Container(
  • color: Colors.blue,
  • height: 30,
  • width: 30
  • child: TextButton(
  • child: const Text("$numClicks")
  • )
  • );
  • }
  • }
  • class BlueSquareParent extends StatefulWidget {
  • BlueSquareParentState createState() => BlueSquareParentState();
  • }
  • class BlueSquareParentState extends State<BlueSquareParent>{
  • //Initialize the number of clicks to 0
  • int numClicksTotal = 0;
  • @override
  • Widget build(){
  • return Scaffold(
  • body: Column(
  • children: [
  • BlueSquare(numClicks: numClicksTotal),
  • BlueSquare(numClicks: numClicksTotal)
  • ]
  • )
  • );
  • }
  • }
  • ```
  • In the `BlueSquare` example, we need to return the number of clicks to the `BlueSquareParent` widget so it knows how many there are. We can do this by passing a callback method to the `BlueSquares` that will let them update the number of clicks in `BlueSquareParent`.
  • ```flutter
  • class BlueSquare extends StatelessWidget{
  • final int numClicks;
  • final Function callback;
  • BlueSquare({
  • required this.numClicks,
  • required this.callback
  • }) : super();
  • Widget build(BuildContext context){
  • Container(
  • color: Colors.blue,
  • onTap: (){
  • callback();
  • }
  • height: 30,
  • width: 30
  • child: TextButton(
  • child: const Text("$numClicks")
  • )
  • );
  • }
  • }
  • class BlueSquareParent extends StatefulWidget {
  • BlueSquareParentState createState() => BlueSquareParentState();
  • }
  • class BlueSquareParentState extends State<BlueSquareParent>{
  • //Initialize the number of clicks to 0
  • int numClicksTotal = 0;
  • @override
  • Widget build(){
  • return Scaffold(
  • body: Column(
  • children: [
  • BlueSquare(numClicks: numClicksTotal, callback: addClick),
  • BlueSquare(numClicks: numClicksTotal, callback: addClick)
  • ]
  • )
  • );
  • }
  • void addClick(){
  • setState((){
  • numClicksTotal++;
  • });
  • }
  • }
  • ```
  • (All code adapted from the examples in the article.)
  • Another example: [This YouTube tutorial](https://www.youtube.com/watch?v=ZqEouycRSzY&list=PLPo5vEiJO3Bigfo2wMYF5xtLjwXJqsPTz&index=7&t=3113s) shows how to lift up state for `TextFormFields` so that the values put into those fields are stored in a parent widget. The child widget (`RangeSelectorTextFormField`) has a `TextFormField` in it and receives a callback method just like the `BlueSquare` widget in the first example. When the text in the field is saved, the callback method is called. In the parent widget, we create a function that sets either the minimum value or the maximum value variable in the parent widget, depending on which text field we're creating, and pass that as the callback method for the `RangeSelectorTextFormField`. Then, when the text in the the `TextFormField` is saved, `RangeSelectorTextFormField` calls the callback method, which sets the associated variable in the parent widget.
  • [Flutter documentation](https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple) recommends using `Provider` instead of lifting up state this way if you're doing anything much more complicated than the example above.
  • (Original post on StackOverflow [here](https://stackoverflow.com/questions/74058512/simple-explanation-of-lifting-state-up/74058928#74058928))
#1: Initial revision by user avatar tarhalda‭ · 2023-06-21T21:58:10Z (11 months ago)
[This article](https://medium.com/nerd-for-tech/lifting-state-up-and-callbacks-7a19d0bdbe53) has a good explanation of lifting state up in Flutter.

>Let's say for example that we have a `BlueSquare` widget that displays the number of times it has been tapped. Each click on the square automatically updates the text displayed with the updated total number of clicks on that square. Let's say then that we wanted to have a set of `BlueSquares` and all the `BlueSquares` in that set display the accumulated number of clicks the user has done.

This means the number of clicks is a state shared by all the `BlueSquare` objects.

(Grammar and some minor phrasing corrected in quote above.)

Instead of making `BlueSquare` a `StatefulWidget`, we make it a `StatelessWidget` and make its parent a `StatefulWidget`. The `StatefulWidget`, `BlueSquareParent`, keeps track of the number of clicks. It passes the number of clicks to the `BlueSquare` widget's constructor so that `BlueSquare` widget can display the current click count.

```flutter
class BlueSquare extends StatelessWidget{
    final int numClicks;

    BlueSquare({
        required this.numClicks
    }) : super();

    Widget build(BuildContext context){
        Container(
            color: Colors.blue,
            height: 30,
            width: 30
            child: TextButton(
                child: const Text("$numClicks") 
            )
        );
    }

}
class BlueSquareParent extends StatefulWidget {
    BlueSquareParentState createState() => BlueSquareParentState();
}

class BlueSquareParentState extends State<BlueSquareParent>{
    //Initialize the number of clicks to 0
    int numClicksTotal = 0;

    @override
    Widget build(){
        return Scaffold(
            body: Column(
                children: [
                    BlueSquare(numClicks: numClicksTotal),
                    BlueSquare(numClicks: numClicksTotal)
                ]
            )
        );
    }

}
```

In the `BlueSquare` example, we need to return the number of clicks to the `BlueSquareParent` widget so it knows how many there are. We can do this by passing a callback method to the `BlueSquares` that will let them update the number of clicks in `BlueSquareParent`.

```flutter
class BlueSquare extends StatelessWidget{
    final int numClicks;
    final Function callback;

    BlueSquare({
        required this.numClicks,
        required this.callback
    }) : super();

    Widget build(BuildContext context){
        Container(
            color: Colors.blue,
            onTap: (){
              callback();
            }
            height: 30,
            width: 30
            child: TextButton(
                child: const Text("$numClicks") 
            )
        );
    }

}
class BlueSquareParent extends StatefulWidget {
    BlueSquareParentState createState() => BlueSquareParentState();
}

class BlueSquareParentState extends State<BlueSquareParent>{
    //Initialize the number of clicks to 0
    int numClicksTotal = 0;

    @override
    Widget build(){
        return Scaffold(
            body: Column(
                children: [
                    BlueSquare(numClicks: numClicksTotal, callback: addClick),
                    BlueSquare(numClicks: numClicksTotal, callback: addClick)
                ]
            )
        );
    }

    void addClick(){
        setState((){
            numClicksTotal++;
        });
    }

}
```

(All code adapted from the examples in the article.)

Another example: [This YouTube tutorial](https://www.youtube.com/watch?v=ZqEouycRSzY&list=PLPo5vEiJO3Bigfo2wMYF5xtLjwXJqsPTz&index=7&t=3113s) shows how to lift up state for `TextFormFields` so that the values put into those fields are stored in a parent widget. The child widget (`RangeSelectorTextFormField`) has a `TextFormField` in it and receives a callback method just like the `BlueSquare` widget in the first example. When the text in the field is saved, the callback method is called. In the parent widget, we create a function that sets either the minimum value or the maximum value variable in the parent widget, depending on which text field we're creating, and pass that as the callback method for the `RangeSelectorTextFormField`. Then, when the text in the the `TextFormField` is saved, `RangeSelectorTextFormField` calls the callback method, which sets the associated variable in the parent widget.

[Flutter documentation](https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple) recommends using `Provider` instead of lifting up state this way if you're doing anything much more complicated than the example above.