Flutter Basics: The differences between Stateless Widget and Stateful Widget

What is a Widget in Flutter?

This must be the very first topic that everybody who starts coding Flutter has come across. You may wonder what is a Widget? Well, I can summarize it for you.

Widget is everything in Flutter.

The people who created Flutter had made Basic built-in Widgets for developers so the developers won’t have to create everything from scratch themselves. Here are some examples; Text, Row, Column, Button, Container, etc. For more examples, you can look them up on the following link.

Despite the Basic Widgets Flutter has provided us, they still cannot deliver everything needed for all different applications. So Flutter allows us (developer) to create one ourselves. But before that, we must understand how Widgets work.

There are 2 types of Flutter Widgets.

  1. Stateless Widget
  2. Stateful Widget

What is a Stateless Widget?

Stateless Widget is a Widget that would be built only once and will never be changed.

A Stateless Widget is an immutable Widget. It means that after the Widget is built at runtime, it will not change its value, appearances, and states later on. The only way to change a Stateless Widget is to destroy it completely and build it again. This process is triggered by an external event.

Example

From the code

  1. There is a Stateless Widget called MyApp.
  2. MyApp is a class that extends from StatelessWidget class. That makes it a Stateless Widget.
  3. MyApp has an overridden method called build(…) (Line 9). You can see the override annotation above it. (Line 8)
  4. When MyApp Widget is built the build method will be called. Good to know that the build method is called only once.
  5. After MyApp is built, it returns a Text Widget which holds a string value “Hello World”.

Stateless Widgets are useful on the part of the application that is static or doesn’t depend on other parts.

What is a Stateful Widget?

A Stateful Widget is a Widget whose values or states can be changed internally at any specific time.

A Stateful Widget, as the name implies, whose values can be changed internally at runtime.

Let’s say we have a Stateful Widget that is a counter that starts counting from zero. When the widget is initialized, the UI will render a number zero. But when the counter is incremented to one, the UI that renders the number zero must change and the number to one. From this basic example, you can see that the state of the Counter widget is its counter value. When the counter value is changed, the Counter widget must be rebuilt to show the current value.

Example

I will demonstrate how to use a Stateful Widget. The example is derived from the Flutter App when you first created a Flutter project. Here is the widget tree of the example.

Widget tree

From the widget tree, there are three things we need to focus on.

  1. Counter: A Stateful Widget
  2. FloatingActionButton: A button that receives user interaction. This button will increment the _counter variable and causes the Counter Widget to be rebuilt.
  3. Text: A Stateless Widget that renders the value of the variable _counter.

When you press the FloatingActionButton widget, the number showing on the app will increment by one. The code is shown below.

From the code

  1. A class called Counter (Line17) extends from the Stateful Widget class that makes it a Stateful Widget.
  2. Counter has an overridden method createState(). This method creates a state object which is mutable. The result of calling createState() is a class called _CounterState.
  3. _CounterState (Line26) extends from State of type Counter (so it’s written as State<Counter>).
  4. In _CounterState, there is an overridden method build(…) just like the Stateless Widget. The build method renders the UI of this state object.
  5. In _CounterState, there is also another overridden method _incrementCounter(). This method calls setState() which is the heart of the Stateful Widget. setState() will scan whether our widget’s state has changed. If there’s a change, it will rebuild the changed part of the widget. In our case, when the counter variable is changed, the Text Widget that wraps around it will get rebuilt.

The below gif is the result of running the app.

Stateful Demo App

FAQ

Q: So you’re saying that a Stateless Widget cannot change at runtime like a Stateful Widget. But what if we want to change the value of the Stateless Widget. Can it be done?

A: Yes. But the principle of rebuilding a Stateless Widget is different from the Stateful Widget. How the Stateful Widget is rebuilt is by calling setState(). As I said, after calling setState(), it will scan the Widget for the changed state and then rebuild that changed part. It means that the Stateful Widget can be rebuilt as many times as you want. On the other hand, the Stateless Widget will be built only once when it is first created at runtime. But sometimes it looks like the Stateless Widget is changing its value right? Actually, when an external event triggers like calling setState() from the parent Stateful Widget, the Stateless Widget will be destroyed completely and then rebuilt again.

Q: Can we use only Stateful Widgets and not use Stateless Widgets? It seems like a Stateful Widget can do every a Stateless Widget can.

A: Yes. By default, a Stateful Widget and a Stateless Widget are Widgets. It works mostly the same. But using only Stateful Widgets could cause performance issues.
Stateful Widget needs more code, more memory, and has a bigger underlying logic compared to Stateless Widget. It will cause our apps to use more resources like CPU or RAM than it is actually needed.
Stateful Widget is nice to use where our Widget has values that need to be changed. Other than that, if your Widget doesn’t need to be changed and is static, I would recommend using a Stateless Widget.

References

Writing code for a living. Tinkering stuff in my free time. Have some coffee, shall we?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store