Paramclasses Academy - Blog

Tutorials Details

←
Post 21 of 40
→

Flutter State Management Explained: setState and When to Use It | Param Classes

Flutter State Management Explained: setState and When to Use It | Param Classes

November 2, 2026

❖ Flutter State Management Explained: setState and When to Use It

❖ Welcome to Param Classes!

When you build a Flutter application, you often need to change what appears on the screen according to user actions.

For example:

  • A counter increases when the user taps a button.

  • A Like button changes its color when selected.

  • A shopping cart displays the updated number of products.

  • A login screen displays a message after submitting a form.

  • A profile page updates when the user changes their name.

How does Flutter update the screen when the data changes?

The answer is State Management.

State management is an important concept in Flutter app development. It helps you manage application data and update the user interface whenever necessary.

Flutter provides a simple method called setState() for managing local widget state.

In this tutorial by Param Classes, you will learn what state management means, understand StatefulWidget and setState, and build practical examples step by step.

✦ 1. What Is State Management in Flutter?

State means the data or information that can change while an application is running.

For example, imagine a counter application. Initially, the counter value is 0. When the user taps the Increase button, the value changes to 1.

Here, the counter value is called the state of the application.

Other examples of state include:

  • User login status.

  • Selected navigation tab.

  • Product quantity.

  • Form input values.

  • Dark mode selection.

  • Favourite or Like button status.

State Management is the process of storing, updating and managing this changing data in an application.

When the state changes, Flutter needs to rebuild the relevant user interface to show the updated information.

✦ 2. Understanding StatelessWidget and StatefulWidget

Flutter provides two important widget types:

A. StatelessWidget

A StatelessWidget is used when the widget does not manage changing internal state.

Example:

import 'package:flutter/material.dart';

class WelcomePage extends StatelessWidget {
  const WelcomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text(
          "Welcome to Param Classes",
          style: TextStyle(fontSize: 22),
        ),
      ),
    );
  }
}

In this example, the displayed text does not change through internal widget state.

B. StatefulWidget

A StatefulWidget is used when a widget needs to manage changing data.

For example, a counter application needs to update its value whenever a user taps a button.

import 'package:flutter/material.dart';

class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {
  int counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text("Counter: $counter"),
      ),
    );
  }
}

Here:

  • StatefulWidget creates a widget that can manage changing state.

  • createState() creates its associated State object.

  • _CounterPageState stores the changing data.

  • counter is the variable that holds the current value.

✦ 3. What Is setState() in Flutter?

setState() is a method provided by Flutter's State class.

It tells Flutter that the internal state of a widget has changed and that the widget should rebuild its user interface.

The basic syntax is:

setState(() {
  // Update your state variables here
});

For example:

setState(() {
  counter++;
});

When this code runs, the counter value increases and Flutter schedules the widget to rebuild.

Important: Changing a variable alone does not automatically tell Flutter to rebuild the widget. For state managed by a StatefulWidget, use setState() when you want the interface to reflect that change.

✦ 4. Create a Simple Counter App Using setState()

Let's create a practical counter application.

The application will contain:

  • A counter value.

  • An Increase button.

  • A Decrease button.

  • A Reset button.

✦ Complete Code

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: CounterPage(),
    );
  }
}

class CounterPage extends StatefulWidget {
  const CounterPage({super.key});

  @override
  State<CounterPage> createState() => _CounterPageState();
}

class _CounterPageState extends State<CounterPage> {

  int counter = 0;

  void increaseCounter() {
    setState(() {
      counter++;
    });
  }

  void decreaseCounter() {
    setState(() {
      if (counter > 0) {
        counter--;
      }
    });
  }

  void resetCounter() {
    setState(() {
      counter = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter Counter App"),
      ),

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

            const Text(
              "Counter Value",
              style: TextStyle(fontSize: 22),
            ),

            const SizedBox(height: 15),

            Text(
              "$counter",
              style: const TextStyle(
                fontSize: 45,
                fontWeight: FontWeight.bold,
              ),
            ),

            const SizedBox(height: 25),

            ElevatedButton(
              onPressed: increaseCounter,
              child: const Text("Increase"),
            ),

            ElevatedButton(
              onPressed: decreaseCounter,
              child: const Text("Decrease"),
            ),

            ElevatedButton(
              onPressed: resetCounter,
              child: const Text("Reset"),
            ),

          ],
        ),
      ),
    );
  }
}

✦ How Does This Application Work?

  1. The counter variable starts with the value 0.

  2. When the user taps Increase, increaseCounter() runs.

  3. setState() updates the counter value.

  4. Flutter rebuilds the widget to display the new value.

  5. Decrease reduces the value, but does not allow it to go below zero.

  6. Reset changes the value back to zero.

This is one of the easiest ways to understand state management in Flutter.

✦ 5. Change Widget Color Using setState()

State management is not limited to numbers. You can also update colors, text and other UI properties.

Let's create a button that changes its background color whenever the user taps it.

✦ Complete Example

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: ColorPage(),
    );
  }
}

class ColorPage extends StatefulWidget {
  const ColorPage({super.key});

  @override
  State<ColorPage> createState() => _ColorPageState();
}

class _ColorPageState extends State<ColorPage> {

  Color boxColor = Colors.blue;

  void changeColor() {
    setState(() {
      if (boxColor == Colors.blue) {
        boxColor = Colors.red;
      } else {
        boxColor = Colors.blue;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Change Color Example"),
      ),

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

            Container(
              height: 150,
              width: 150,
              color: boxColor,
            ),

            const SizedBox(height: 25),

            ElevatedButton(
              onPressed: changeColor,
              child: const Text("Change Color"),
            ),

          ],
        ),
      ),
    );
  }
}

Explanation:

  • boxColor stores the current color.

  • changeColor() checks the existing color.

  • If the color is blue, it changes to red.

  • If the color is red, it changes to blue.

  • setState() refreshes the interface.

This concept is useful for theme settings, selected buttons and interactive UI elements.

✦ 6. Create a Like Button Using setState()

A Like button is another common example of state management.

When the user taps the button, the heart icon changes its color and the Like count increases or decreases.

✦ Complete Code

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: LikePage(),
    );
  }
}

class LikePage extends StatefulWidget {
  const LikePage({super.key});

  @override
  State<LikePage> createState() => _LikePageState();
}

class _LikePageState extends State<LikePage> {

  bool isLiked = false;
  int likeCount = 0;

  void toggleLike() {
    setState(() {
      isLiked = !isLiked;

      if (isLiked) {
        likeCount++;
      } else {
        likeCount--;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Like Button Example"),
      ),

      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

            IconButton(
              onPressed: toggleLike,
              icon: Icon(
                isLiked ? Icons.favorite : Icons.favorite_border,
                color: isLiked ? Colors.red : Colors.grey,
                size: 60,
              ),
            ),

            Text(
              "Likes: $likeCount",
              style: const TextStyle(fontSize: 22),
            ),

          ],
        ),
      ),
    );
  }
}

Explanation:

  • isLiked stores whether the button is selected.

  • likeCount stores the number of likes.

  • !isLiked changes true to false or false to true.

  • The heart icon changes according to the current state.

  • The Like count updates when the user taps the icon.

This example can help you understand how social media applications manage simple interactions.

✦ 7. When Should You Use setState()?

setState() is useful when the changing data belongs to a single widget or a small part of your application.

You can use it for:

  • Counter applications.

  • Show and hide password buttons.

  • Changing a selected tab.

  • Expanding and collapsing sections.

  • Changing button colors.

  • Showing or hiding UI elements.

  • Managing small form interactions.

For example, a password visibility button can use a Boolean variable:

bool isPasswordVisible = false;

void togglePassword() {
  setState(() {
    isPasswordVisible = !isPasswordVisible;
  });
}

You can then use this value in a TextField:

TextField(
  obscureText: !isPasswordVisible,
  decoration: const InputDecoration(
    labelText: "Password",
  ),
)

The password visibility changes whenever the Boolean value changes.

✦ 8. When Should You Avoid Using Only setState()?

setState() is simple and useful, but it may not be the best solution for every application.

Consider a large application with:

  • Login and user profile data.

  • Shopping cart information.

  • Multiple screens using the same data.

  • Complex application settings.

  • Data shared between unrelated widgets.

If many widgets need access to the same state, passing data and callbacks through multiple widget levels can become difficult.

In such cases, developers may use other state management approaches, such as:

  • Provider.

  • Riverpod.

  • BLoC.

  • Cubit.

  • GetX.

These approaches help organize and share application state in larger projects.

You do not need to learn all of them immediately. Start with StatefulWidget and setState(), then move to more advanced approaches when your projects require them.

✦ 9. Common Mistakes Beginners Should Avoid

When learning Flutter state management, beginners sometimes make these mistakes:

1. Changing Variables Without setState()

If you update a State variable without calling setState(), the UI may not reflect the change immediately.

2. Using StatefulWidget Everywhere

Not every widget needs to manage changing state. Use StatelessWidget when the widget does not need its own changing internal state.

3. Putting Too Much Logic Inside setState()

Keep your code organized. Perform necessary calculations and place the state updates inside the setState() callback.

4. Calling setState() After a Widget Is Disposed

Do not call setState() after the State object has been removed from the widget tree. For asynchronous operations, check mounted before updating the state.

5. Managing Shared Data in Too Many Places

When several screens need the same information, consider a suitable shared state management solution instead of duplicating the same data.

✦ 10. Practice Tasks for Beginners

After completing this tutorial, try these exercises:

  1. Create a counter app with Increase, Decrease and Reset buttons.

  2. Create a button that changes its background color.

  3. Build a Like button with a changing heart icon.

  4. Create a password visibility toggle.

  5. Build a simple app that switches between Light Mode and Dark Mode.

  6. Create an expandable section that displays additional information when tapped.

Try to build these projects without copying the complete code. This will improve your understanding of Flutter state management.

❖ Conclusion

State management is one of the most important concepts in Flutter app development. It allows applications to respond to user actions and display updated information.

In this tutorial, you learned what state management means, how StatelessWidget and StatefulWidget work, how to use setState(), and how to build practical examples such as a counter app, color-changing box and Like button.

For beginners, setState() is an excellent starting point. Once you understand local state management, you can explore advanced solutions such as Provider and Riverpod.

At Param Classes, we believe in learning programming through practical examples and real-world projects. Keep practicing and gradually build more interactive Flutter applications.

Learn Today, Grow Tomorrow with Param Classes!

←
Post 21 of 40
→