Managing State in Flutter

Sep 22 2022 · Dart 2.17, Flutter 3.0, Android Studio Chipmunk

Part 1: Understand State Management

04. Use Set State

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 03. Meet the Sample App Next episode: 05. Add a Value Notifier

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 04. Use Set State

One of the first tools in your state management toolkit is setState. This is a method defined the state class. When you call setState, you pass in a void callback which is called right away. This callback should only contain changes that affect any changes to current state. Everything else should be placed outside of the set state callback.

Once setState is called, the Flutter Framework is notified that a rebuild is necessary at which point, Flutter will rebuild the current widget and all the widgets in the subtree.

There is one key thing to note - set state will only rebuild the current widget subtree. Now imagine you had a widget tree like the following. One button increments the counter, yet the text label for the counter exists in a sibling widget. So what happens when the user taps the increment button? What does the counter say? You would think it increment to eleven, but it doesn’t. It remains fixed at ten.

This is because when the setState method is called in the elevated button, it rebuilds the button and all the child widgets. Since the sibling widget tree isn’t a part of that tree, it doesn’t get rebuilt. The state of the counter is eleven, but the user interface reads ten because the existing widgets have yet to be rebuilt. Let’s take a look at this closer and see how we might solve this.

To get started, open up the sample project for this episode. Build and run the sample app.

You’ll see a button that represents the amount of Flutter articles on the site. You’ll see it reads 115 articles and the total tutorials being 115. Tap the button.

It should increase the amount of articles, but instead prints a message to the console. The total tutorials text label should increase with the Flutter tutorials. Let’s get this working. Remember, we want to start high up in the widget tree and pass our state down. Our state object is represented by the pillar class. Open main.dart. Add the following to the top of the page:

import 'models/pillar.dart';

This allows our code to access the pillar. Now to create a Pillar data object. In _ApplicationState, add the following:

final pillarData = Pillar(type: PillarType.flutter, articleCount: 115);

Here we’ve created a variable that contains a Pillar model object. We’ve set it to be a Flutter and an article count of 115. Now to pass it down the widget tree.

You’ll see that our ApplicationState creates a TutorialsPage widget. Then, inside the TutorialsPage, a TutorialWidget is created. Inside the widget, we display the data. Let’s start in the TutorialWidget and work our way up. In TutorialWidget, import pillar.dart.

import '../models/pillar.dart';

Next, add a pillar constant and update the constructor to use it.

  final Pillar pillar;
  const TutorialWidget({required this.pillar, super.key});

This naturally creates an error because we changed the tutorial widget to require a pillar. Open tutorials_page.dart and add the following.

import '../models/pillar.dart';
final Pillar pillar;
const TutorialsPage({required this.pillar, super.key});

Now pass the pillar into the TutorialWidget, making sure to update the const values.

children: <Widget>[
  Center(child: TutorialWidget(pillar: widget.pillar)),
  const Padding(

There’s one last compile error to address. Open main.dart. Pass in the pillar model object.

body: TutorialsPage(pillar: pillarData),

Okay, now to use the data object. Open tutorial_widget.dart. First, increase the amount of articles when the user taps the button. Because this represents a state change, we need to let the framework know by wrapping it in setState().

setState(() {
  widget.pillar.increaseArticleCount();
});

Next, use the image included with the pillar.

Image.asset('assets/images/${widget.pillar.type.imageName}', width: 110, height: 110),

Then update the text to display the correct amount of articles.

Positioned(
          bottom: 2,
          child: CircleAvatar(
            backgroundColor: Colors.blue,
            child: Text(widget.pillar.articleCount.toString()),
          ),
        )

Finally, we need to update the total pillar count. Open up tutorials.page.dart. Change the Total Tutorials text to use the pillar data.

Padding(
          padding: const EdgeInsets.only(top: 24.0),
          child: Text(
            'Total Tutorials: ${widget.pillar.articleCount}',
            style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
          ),
        )

Notice we are deferring the tutorial count to one pillar. Later, we can change this to use the data from all the pillars.

Now before we build and run, review the changes that we’ve just made. See that we declared our state in our application widget and passed it down via. constructors. Both the tutorials_page and the tutorial widget both use the state.

Now say we needed to add another series of widgets. Those widgets would also need constructors that take in pillar, even if those widgets have nothing to do with the pillar. All you are doing is creating a pass through which when used outside the context of this widget arrangement, makes no sense. But we’ll get to that soon enough. Okay build and run. Once running, tap on the Flutter button.

You’ll notice that the Flutter articles increase by one but the total articles remain the same. That’s because the tutorial widget and children are updated. The Total Tutorials text is an adjacent widget tree so it isn’t affected. We need a way to notify the total tutorials that something has changed and for this, we’ll meet the value notifier. Come at you in the next episode.