What is Flutter Stateful and Stateless Widgets

Introduction

When building a Flutter app, the state is a critical concept. It refers to anything stored in the app’s memory while it’s running. This includes UI elements such as buttons, text, icons, and animations. But how do these states tie into the different types of widgets in Flutter? Let’s dive into the difference between stateful and stateless widgets.

You can also watch this very helpful video.

Flutter Stateful and Stateless Widgets

What is State?

State refers to the information that a widget holds, which can be read synchronously when the widget is constructed. This data might change over the widget’s lifetime. In simpler terms, the state is the current data or status of the widget’s properties at the time of its creation. For example, a CheckBox widget will have a different state when it is checked or unchecked.

Stateless Widgets

Stateless widgets are immutable, meaning once they are built, their state cannot change. No matter how much the underlying data or variables change, the widget’s appearance remains the same. Stateless widgets are ideal for static content that doesn’t change during runtime. A basic stateless widget might look like this:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

In this example, the MyApp widget is stateless. It extends the StatelessWidget class and overrides the build method, which returns a widget (in this case, a Container). The build method is called once, rendering the UI, and it does not re-render even if the app’s data changes.

Here’s another example where the stateless widget displays a simple UI:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: const Color.fromARGB(255, 230, 255, 201),
        appBar: AppBar(
          leading: const Icon(Icons.menu),
          backgroundColor: Colors.green,
          title: const Text(
            "My App",
            textAlign: TextAlign.start,
          ),
        ),
        body: const Center(
          child: Text(
            "Stateless Widget",
            style: TextStyle(color: Colors.black, fontSize: 30),
          ),
        ),
      ),
    );
  }
}

In this case, the text “Stateless Widget” is displayed in the center of the screen. Since the widget is stateless, this UI remains unchanged throughout the app’s lifecycle.

Stateful Widgets

On the other hand, stateful widgets are dynamic, meaning their state can change during their lifecycle. These widgets are ideal for situations where the UI needs to update based on user interaction or other factors. Stateful widgets override the createState method, which returns a State object to manage changes.

Here’s a basic example:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

In this example, the MyApp widget is stateful, meaning it can change state during its lifecycle. The createState method returns an instance of _MyAppState, where the actual state management and UI building occur.

Here’s a more detailed example:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        backgroundColor: const Color.fromARGB(255, 230, 255, 201),
        appBar: AppBar(
          leading: const Icon(Icons.menu),
          backgroundColor: Colors.green,
          title: const Text(
            "My App",
            textAlign: TextAlign.start,
          ),
        ),
        body: const Center(
          child: Text(
            "Stateful Widget",
            style: TextStyle(color: Colors.black, fontSize: 30),
          ),
        ),
      ),
    );
  }
}

In this stateful example, the UI could be re-rendered whenever the state within _MyAppState changes. This dynamic behavior is crucial for apps that require frequent UI updates based on user interactions or other real-time data.

Conclusion

Stateless widgets are perfect for static content that doesn’t change, while stateful widgets are better suited for dynamic interfaces that need to respond to user input or other changes. Understanding when to use each type of widget is essential for efficient Flutter development.

Show Your Support

Official Documentation Here.

Explore Other Flutter Topics…

  1. What is Flutter
  2. Page Transition in Flutter
  3. Web Animation in Flutter
  4. Flutter Injectable
  5. Dependency Injection in Flutter
  6. Async and Await in Flutter
  7. Flutter Reusable Custom Widget
  8. Build Responsive UIs in Flutter using MediaQuery

9 Responses

Leave a Reply

Your email address will not be published. Required fields are marked *