Menu
CoddyTech

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 icon

Challenge

Medium

Make the page the only owner of the likes:

  • Turn LikeButton into a StatelessWidget with two fields: likes and an onLike callback.
  • The page passes its own likes, and an onLike that adds 1 inside setState.

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)),
      ],
    );
  }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in State Management

Practice on your own: Online Flutter compiler