> ## Content Index
> Fetch the complete content index at: https://arkar.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# Day 17: Stateful Widgets & Lifecycle
- URL: https://arkar.dev/day-17-stateful-widgets-lifecycle/
- Published: 2026-01-19T14:45:44.000Z
- Updated: 2026-01-19T14:45:44.000Z
- Description: Master Flutter's StatefulWidget lifecycle from birth to death! Learn how setState() triggers rebuilds, when to use initState/dispose, and Flutter's internal update decision algorithm. Perfect for developers moving from basics to production-ready apps.
- Author: Arkar Min Tun
- Tags: 100 days of flutter, flutter

ဒီနေ့မှာတော့ မနေ့က ဆွေးနွေးသွားတဲ့ Stateless widget တွေရဲ့အဆက်ဖြစ်တဲ့ Stateful Widgets တွေအကြောင်းရယ်၊ သူ့ရဲ့ lifecycle နဲ့ ပတ်သက်တာတွေကို ဆက်လက်ပြီး ဆွေးနွေးသွားပါမယ်။

မနေ့က ဆွေးနွေးခဲ့တဲ့ Stateless widget ဆိုတာ ပုံသေကားချပ်လိုမျိုး ပြောင်းမရ​ ပြင်မရ အမျိုးအစားလို့ ပြောလို့ရပါတယ်။ သူ့ကို ပြောင်းချင်တဲ့အခါ အပြင်က value အသစ် ထည့်ပေးရုံက လွဲပြီးတော့ သူ့ထဲမှာက ပြောင်းလဲတာတွေ လုပ်လို့မရပါဘူး။ ဒါကို immutable ဖြစ်တယ်လို့လဲ​ခေါ်ပါတယ်။

```dart
class BrokenCounter extends StatelessWidget {
  int count = 0; // ❌ Can't change!

  @override
  Widget build(BuildContext context) {
    return Text('Count: $count');
  }
}
```

ဒီမှာဆို `count` ဆိုတဲ့ value ကို stateless widget ထဲမှာ ကြေငြာထားတာဖြစ်တဲ့အတွက် ဒီ value ကို အပြောင်းအလဲ လုပ်ပေးလို့မရပါဘူး။ ဒီတော့ interactive ဖြစ်တဲ့ UI တွေ တည်ဆောက်ချင်တဲ့အခါ ဘယ်လို လုပ်ကြမလဲ? ဒါကိုတော့ Stateful widget တွေ သုံးပြီးတော့ ဖြေရှင်းလို့ ရပါတယ်။

## Stateful Widget

Stateful widget လို့ပြောရင် သူ့မှာ ၂ပိုင်းရှိပါတယ်။ တခုကတော့ widget ဖြစ်ပြီး နောက်တခုကတော့ state ပါ။

![](https://arkar.dev/content/images/2026/01/image-54.png)

```dart
// THE SHELL (Immutable Configuration)
class CounterPage extends StatefulWidget {
  const CounterPage({super.key});
  
  @override
  State<CounterPage> createState() => _CounterPageState();
}

// THE BRAIN (Mutable Logic)
class _CounterPageState extends State<CounterPage> {
  int _count = 0; // This CAN change!
  
  @override
  Widget build(BuildContext context) {
    return Text('Count: $_count');
  }
}
```

#### **The Widget Class**

ဒါကိုတော့ အခွံလို့ မြင်ကြည့်လို့ရပါတယ်။ Stateless လိုမျိုးပဲ immutable ဖြစ်ပါတယ်။ သူ့ထဲမှာ value တွေကို ပြောင်းလဲလို့မရပါဘူး။

#### **The State Class**

ဒါကတော့ အဓိလုပ်ဆောင်ချက်တွေ ပါဝင်တဲ့ အစိတ်အပိုင်းပဲ ဖြစ်ပါတယ်။ mutable ဖြစ်နေမှာ ဖြစ်ပြီးတော့ သူ့ထဲက ပြောင်းလဲနေမယ့် data တွေကို ကိုယ်တိုင်ကိုယ်ကျ ကိုင်တွယ်ပေးပါတယ်။

State ကိုတော့ ရေးရင် underscore (\_) နဲ့ ရေးပါတယ်။ (e.g., `_CounterPageState`) ဒီလိုရေးတာ dart ရဲ့ private အဖြစ် ကြေငြာတာလို့ ပြောခဲ့ပြီးသား ဖြစ်ပါတယ်။ အခုလို ကြေငြာလိုက်ခြင်းအားဖြင့် State class က Widget class တခုထဲက ခေါ်သုံးလို့ရတဲ့ private class ဖြစ်သွားပါတယ်။

## Update State

ဒီတော့ stateful widget ထဲက value ကို ဘယ်လိုမျိုး အပြောင်းအလဲ လုပ်သလဲဆိုတော့ `setState` ဆိုတဲ့ function ကို ခေါ်ပြီး update လုပ်ပါတယ်။​ 

```dart
void _increment() {
  setState(() {
    _count++; // Change happens HERE
  });
}
```

`setState` ထဲမှာ ထည့်ရေးလိုက်ခြင်းအားဖြင့် အောက်မှာပေးထားတဲ့ အဆင့်တွေ တခုပြီးတခု Flutter engine က လုပ်ဆောင်သွားပါတယ်။

1. `setState` ကို ခေါ်ပါတယ်
2. Flutter engine က ဒီ setState ခေါ်လိုက်တဲ့ widget ကို `dirty` ဖြစ်သွားပြီလို့ သတ်မှတ်ပါတယ်
3. Flutter engine ဒီ widget ကို re-build လုပ်ဖို့ ပြင်ဆင်ပါတယ် (schedule လုပ်ပါတယ်)
4. `build` method ကို ထပ်ပြီးတော့ ခေါ်ပါတယ်
5. UI အသစ်ကို ပြပေးပါတယ်

တကယ်လို့ `setState` နဲ့ မခေါ်ဘဲ အခုလိုမျိုး ခေါ်ရင်ရော ဘယ်လို ဖြစ်သွားမယ် ထင်ပါသလဲ?

```
void _increment() {
  count++; // Update value
}
```

ဒီမှာဆို `_count` value ကို တခုတိုးပေးလိုက်တာပဲ ဖြစ်ပါတယ်။ value ပြောင်းသွားပေမယ့် အပေါ်က အဆင့်တွေ ဖြတ်မသွားတဲ့အတွက် UI မှာတော့ ပြောင်းမသွားပါဘူး။

ဒါဆိုရင်တော့ `CounterPage` ဆိုပြီး အပေါ်မှာ ဆွေးနွေးခဲ့တဲ့ implementation တွေကို စုပြီးတော့ ရေးလိုက်ပါမယ်။

```dart
import 'package:flutter/material.dart';

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

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

class _CounterPageState extends State<CounterPage> {
  // Our mutable state
  int _count = 0;

  void _increment() {
    setState(() {
      _count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Stateful Counter")),
      body: Center(
        child: Text(
          "Total Taps: $_count",
          style: const TextStyle(fontSize: 30),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

```

![](https://arkar.dev/content/images/2026/01/image-58.png)

Floating Action Button ကို နှိပ်တိုင်းမှာ `_count` value က ပြောင်းနေမှာပဲ ဖြစ်ပါတယ်။ 

## The Widget Lifecycle

Stateful widget မှာ lifecycle events တွေ ဆိုပြီးတော့ ရှိပါတယ်။ ဒါတွေကတော့ widget တခု စတင်ပြီး တည်ဆောက်တဲ့အချိန်ကနေ နောက်ဆုံး မသုံးတော့လို့ ဖျက်လိုက်တဲ့အထိ သုံးလို့ရတဲ့ callback function တွေပဲ ဖြစ်ပါတယ်။

### Birth

```dart
@override
void initState() {
  super.initState();
  print("Widget is born!");
  // Initialize controllers, fetch API data, start timers
}
```

Widget ကို ပထမဆုံး တည်ဆောက်တဲ့အချိန်တော့ `initState` ကို ခေါ်ပါတယ်။ တကယ်လို့ widget ကို စတဲ့အချိန်မှာ ခေါ်ချင်တဲ့ API တွေ ရှိလို့ဖြစ်ဖြစ်၊ controller တွေ setup လုပ်ချင်တာဖြစ်ဖြစ်၊ timer တွေ စချင်တဲ့အခါဖြစ်ဖြစ် သုံးလို့ရပါတယ်။

### Life

```dart
@override
Widget build(BuildContext context) {
  print("Building UI...");
  return Scaffold(...);
}
```

ဒါကိုတော့ `setState` ကို ခေါ်လိုက်တိုင်းမှာ build method ကို ပြန်ပြီးတော့ run ပါတယ်။ ဒါကြောင့် UI မှာ ပြောင်းထားတဲ့ အသစ်တွေကို မြင်ရတာပဲ ဖြစ်ပါတယ်။

### Death

```dart
@override
void dispose() {
  // Cancel timers, close streams, dispose controllers
  print("Widget is dying...");
  super.dispose();
}
```

ဒါကိုတော့ widget ကို widget tree ကနေ ဖယ်ထုတ်ဖို့ လုပ်တဲ့အခါ မဖျက်ခင် ခေါ်ပါတယ်။​ တကယ်လို့ controller တွေ၊ subscription တွေ၊ timer တွေ ရှိတဲ့အခါ memory leak တွေ မဖြစ်အောင် dispose/close လုပ်ဖို့လိုတဲ့အခါ သုံးပါတယ်။

#### StatelessWidget vs StatefulWidget Preview

| Feature          | StatelessWidget             | StatefulWidget                          |
| ---------------- | --------------------------- | --------------------------------------- |
| **Data Changes** | No (immutable)              | Yes (mutable)                           |
| **Performance**  | ⚡⚡⚡⚡⚡ Faster                | ⚡⚡⚡⚡ Slightly slower                    |
| **Lifecycle**    | Only build()                | initState(), build(), dispose()         |
| **Use Cases**    | Icons, labels, static cards | Forms, animations, interactive elements |
| **Memory**       | Lightweight                 | Small overhead for state management     |

ဒီတော့ stateless widget ကို ဖြစ်နိုင်သလောက် သုံးပြီးတော့ တကယ်လိုတဲ့အခါမှ stateful widget တွေကို သုံးပေးဖို့ တိုက်တွန်းပါတယ်။

တကယ့်လက်တွေမှာ ဘယ်လိုအခြေအနေတွေမှာ Stateful widget တွေ သုံးလဲ​ကြည့်ကြည့်ရအောင်ပါ။

- Instagram Like Button: နှိပ်လိုက်တာနဲ့ icon ပြောင်းလဲတဲ့အခါမျိုး
- Amazon Shopping Cart: item ကို buy ဖို့ နှိပ်လိုက်တာနဲ့ Cart item တိုးသွားတာမျိုး
- Form Fields: user input လုပ်တိုင်း valid ဖြစ်၊မဖြစ် စစ်တာမျိုး

အစရှိတဲ့ အခြေအနေတွေမှာ သုံးပါတယ်။

ဒါဆိုရင်တော့ Stateful widget နဲ့ ပတ်သက်ပြီး အတော်လေး သိလောက်ပြီ ထင်ပါတယ်။

---

ဒီနေ့ Day 17 အတွက်ကတော့ ဒီလောက်ပဲ ဖြစ်ပါတယ်။ အဆုံးထိ ဖတ်ပေးတဲ့အတွက် အများကြီး ကျေးဇူးတင်ပါတယ်။ နားမလည်တာတွေ အဆင်မပြေတာတွေ ရှိခဲ့ရင်လဲ အောက်မှာပေးထားတဲ့ discord server ထဲမှာ လာရောက်ဆွေးနွေးနိုင်ပါတယ်။ နောက်နေ့တွေမှာလဲ ဆက်လက်ပြီး sharing လုပ်သွားပေးသွားမှာ ဖြစ်တဲ့အတွက် subscribe လုပ်ထားဖို့ ဖိတ်ခေါ်ပါတယ်။

- Youtube: [https://www.youtube.com/@arkarmintun](https://www.youtube.com/@arkarmintun?ref=arkar.dev)
- Newsletter: <https://arkar.dev/>
- Discord: [https://discord.gg/3xUJ6k6dkH](https://discord.gg/3xUJ6k6dkH?ref=arkar.dev)

---