Beranda Coding Navigation dan State Management Flutter untuk Pemula
CodingFlutter

Navigation dan State Management Flutter untuk Pemula

Pelajari Navigation dan State Management Flutter dari nol, mulai dari Navigator, Route, passing data, setState, local state, app state, ChangeNotifier, Provider, hingga pola state management.

Bagikan
navigation dan state management flutter
Bagikan

Pada Level 5, kita belajar bagaimana membuat UI menggunakan widget. Kemudian pada Level 6, kita belajar bagaimana menyusun widget tersebut menjadi layout yang responsif terhadap berbagai ukuran layar.

Sekarang kita sudah memiliki fondasi untuk membuat tampilan aplikasi. Namun sebuah aplikasi nyata tentu tidak hanya terdiri dari satu halaman statis.

Pengguna perlu berpindah dari:

Login
   ↓
Home
   ↓
Detail Produk
   ↓
Checkout
   ↓
Pembayaran

Selain itu, tampilan aplikasi juga harus mampu merespons tindakan pengguna.

Misalnya:

User menekan tombol
        ↓
Data berubah
        ↓
UI diperbarui

Atau:

User login
        ↓
Status login berubah
        ↓
Halaman aplikasi berubah

Di sinilah dua konsep penting mulai digunakan: Navigation dan State Management Flutter.

Navigation mengatur perpindahan dan riwayat halaman, sedangkan state management membantu aplikasi mengelola data atau kondisi yang menentukan apa yang harus ditampilkan oleh UI.

Flutter menggunakan pendekatan deklaratif: UI menggambarkan keadaan aplikasi saat ini. Ketika state berubah, UI dibangun kembali agar mencerminkan state terbaru.

Navigation dan state management Flutter merupakan materi pembelajaran Level 7 dari Roadmap Belajar Flutter dari Nol Sampai Siap Kerja yang dibahas pada situs Raja Putra Media.

Apa Itu Navigation Flutter?

Navigation adalah mekanisme untuk berpindah dari satu halaman atau screen ke halaman lainnya.

Contoh sederhana:

Home
  ↓
Detail
  ↓
Checkout

Dalam Flutter, salah satu komponen utama untuk navigation adalah Navigator.

Navigator mengelola kumpulan Route dalam bentuk stack. Ketika halaman baru dibuka, route dapat di-push ke stack. Ketika kembali, route tersebut dapat di-pop.

Secara sederhana:

Navigator Stack

┌─────────────┐
│ Detail      │ ← paling atas
├─────────────┤
│ Home        │
└─────────────┘

Ketika membuka halaman Detail:

Home
 ↓
push(Detail)
 ↓
Home + Detail

Ketika menekan Back:

pop()
 ↓
Home

Konsep stack ini sangat penting untuk memahami navigation Flutter.

Navigator.push()

Cara paling dasar berpindah halaman adalah menggunakan:

Navigator.push()

Contoh:

ElevatedButton(
  onPressed: () {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) {
          return const DetailPage();
        },
      ),
    );
  },
  child: const Text('Lihat Detail'),
)

Ketika tombol ditekan:

Home
 ↓
push()
 ↓
Detail

Flutter menyediakan Navigator untuk pola navigasi imperatif sederhana seperti ini. MaterialPageRoute merupakan salah satu route yang menyediakan transisi halaman bergaya Material.

Navigator.pop()

Untuk kembali ke halaman sebelumnya:

Navigator.pop(context);

Contohnya:

ElevatedButton(
  onPressed: () {
    Navigator.pop(context);
  },
  child: const Text('Kembali'),
)

Jika stack sebelumnya:

Home
Detail

maka:

pop()

akan menghapus Detail dari stack.

Hasilnya:

Home

Memahami Push dan Pop

Cara termudah memahami navigation Flutter adalah dengan membayangkan tumpukan buku.

Misalnya:

Home

Kemudian Anda membuka Detail:

Detail
Home

Kemudian membuka Checkout:

Checkout
Detail
Home

Jika Checkout di-pop:

Detail
Home

Jika Detail di-pop:

Home

Jadi:

push()
= menambahkan route

pop()
= menghapus route teratas

Membuat Halaman Kedua

Contoh sederhana:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).push(
              MaterialPageRoute(
                builder: (context) => const DetailPage(),
              ),
            );
          },
          child: const Text('Buka Detail'),
        ),
      ),
    );
  }
}

Halaman kedua:

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Detail'),
      ),
      body: const Center(
        child: Text('Halaman Detail'),
      ),
    );
  }
}

Dengan kode sederhana tersebut, kita sudah memiliki navigation dasar.

Passing Data Antar Halaman

Navigation menjadi jauh lebih menarik ketika kita ingin mengirim data.

Misalnya Home memiliki produk:

Laptop
Harga: Rp10.000.000

Ketika pengguna memilih produk tersebut, halaman Detail harus mengetahui produk mana yang dipilih. Caranya adalah mengirim data melalui constructor.

Contoh:

class ProductDetailPage extends StatelessWidget {
  const ProductDetailPage({
    required this.productName,
    required this.price,
    super.key,
  });

  final String productName;
  final int price;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(productName),
      ),
      body: Center(
        child: Text(
          'Harga: Rp$price',
        ),
      ),
    );
  }
}

Kemudian dari halaman sebelumnya:

Navigator.of(context).push(
  MaterialPageRoute(
    builder: (context) => ProductDetailPage(
      productName: 'Laptop',
      price: 10000000,
    ),
  ),
);

Alurnya:

Home
  │
  │ kirim productName + price
  ↓
ProductDetailPage

Ini merupakan salah satu pola dasar yang sangat sering digunakan.

Mengembalikan Data dari Halaman

Navigation juga dapat digunakan untuk mengembalikan nilai. Misalnya halaman kedua meminta pengguna memilih kategori.

Halaman pertama dapat menunggu hasil:

final result = await Navigator.of(context).push<String>(
  MaterialPageRoute(
    builder: (context) => const CategoryPage(),
  ),
);

Kemudian halaman kedua:

Navigator.pop(
  context,
  'Flutter',
);

Dengan demikian:

Page A
   ↓
Page B
   ↓
return data
   ↓
Page A

Pola seperti ini berguna untuk:

  • memilih kategori
  • memilih tanggal
  • memilih produk
  • memilih alamat
  • memilih filter
  • mengambil hasil form

Bagaimana dengan Named Routes?

Flutter juga memiliki mekanisme named routes.

Contohnya:

MaterialApp(
  routes: {
    '/': (context) => const HomePage(),
    '/detail': (context) => const DetailPage(),
  },
)

Kemudian:

Navigator.pushNamed(
  context,
  '/detail',
);

Cara ini cukup mudah dipahami oleh pemula.

Baca juga:  Setup Flutter Development Environment untuk Pemula

Namun ada catatan penting.

Dokumentasi Flutter saat ini tidak merekomendasikan named routes untuk sebagian besar aplikasi. Untuk aplikasi sederhana, Flutter merekomendasikan penggunaan Navigator dengan MaterialPageRoute, sedangkan aplikasi dengan kebutuhan routing/deep linking yang lebih kompleks dapat menggunakan Router atau package seperti go_router.

Karena itu, pada tahap belajar:

Navigator + MaterialPageRoute

sudah cukup untuk memahami konsep dasar.

Nanti ketika aplikasi semakin kompleks, kita dapat mempelajari:

go_router

dan routing deklaratif secara lebih mendalam.

Apa Itu State?

Sekarang kita masuk ke bagian kedua Level 7: State Management.

State dapat dipahami sebagai data atau kondisi yang dibutuhkan aplikasi untuk menentukan tampilan UI pada suatu waktu.

Flutter mendefinisikan state secara praktis sebagai data yang diperlukan untuk membangun kembali UI pada kondisi tertentu.

Contoh sederhana:

int counter = 0;

Ketika:

counter = 0

UI mungkin menampilkan:

Counter: 0

Kemudian pengguna menekan tombol:

counter = 1

UI berubah menjadi:

Counter: 1

Jadi:

State
  ↓
UI

Ketika state berubah:

State berubah
  ↓
UI diperbarui

Inilah dasar reactive UI.

Declarative UI Flutter

Flutter menggunakan pendekatan deklaratif.

Daripada mengatakan:

"ubah teks pada label menjadi 10"

kita lebih sering berpikir:

Jika counter = 10,
maka UI harus menampilkan "10".

Secara sederhana:

UI = f(State)

Artinya tampilan merupakan hasil dari state saat ini.

Dokumentasi Flutter menggambarkan pendekatan deklaratif sebagai UI yang mencerminkan state aplikasi saat ini. Ketika state berubah, UI dibangun kembali berdasarkan state baru tersebut.

StatefulWidget dan State

Pada Level 5 kita sudah mengenal StatefulWidget. Sekarang kita akan menggunakannya untuk mengelola state lokal.

Contoh:

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',
        ),
      ),
    );
  }
}

Variabel:

int counter = 0;

merupakan state yang berada di dalam widget tersebut.

Apa Fungsi setState()?

Jika kita hanya mengubah:

counter++;

Flutter tidak otomatis diberi tahu bahwa UI perlu dibangun ulang.

Karena itu kita menggunakan:

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

Contoh lengkap:

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

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

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Counter'),
      ),
      body: Center(
        child: Text(
          '$counter',
          style: const TextStyle(
            fontSize: 32,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: increment,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Alurnya:

User klik tombol
      ↓
increment()
      ↓
setState()
      ↓
counter berubah
      ↓
build()
      ↓
UI menampilkan nilai baru

Flutter sendiri menempatkan setState sebagai pendekatan low-level untuk state yang bersifat widget-specific atau ephemeral.

Apa Itu Local atau Ephemeral State?

Tidak semua state perlu dikelola oleh sistem state management yang kompleks.

Flutter membedakan secara konseptual antara ephemeral state dan app state. Ephemeral state adalah state yang dapat disimpan dengan rapi dalam satu widget.

Contohnya:

Checkbox aktif/tidak

atau:

Index tab saat ini

atau:

Apakah password sedang ditampilkan?

Misalnya:

bool isPasswordVisible = false;

State ini mungkin hanya dibutuhkan oleh satu widget.

Maka:

StatefulWidget
+
setState()

sudah cukup.

Contoh State Lokal: Toggle Password

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

  @override
  State<PasswordField> createState() => _PasswordFieldState();
}

class _PasswordFieldState extends State<PasswordField> {
  bool isVisible = false;

  @override
  Widget build(BuildContext context) {
    return TextField(
      obscureText: !isVisible,
      decoration: InputDecoration(
        suffixIcon: IconButton(
          onPressed: () {
            setState(() {
              isVisible = !isVisible;
            });
          },
          icon: Icon(
            isVisible
                ? Icons.visibility
                : Icons.visibility_off,
          ),
        ),
      ),
    );
  }
}

State:

bool isVisible = false;

hanya berkaitan dengan widget password.

Tidak perlu langsung menggunakan state management package.

Apa Itu App State?

Sekarang bayangkan kondisi yang berbeda.

Misalnya:

Status login

Informasi ini mungkin diperlukan oleh:

Home
Profile
Settings
Checkout
Navigation

Atau:

Shopping Cart

yang dibutuhkan oleh beberapa bagian aplikasi.

Contoh app state:

  • informasi login
  • user preferences
  • shopping cart
  • notification
  • data yang digunakan banyak screen
  • status aplikasi tertentu

Flutter memasukkan login information, user preferences, notifications, dan shopping cart sebagai contoh application state yang dapat digunakan oleh banyak bagian aplikasi.

Local State vs App State

Cara sederhana membedakannya:

Local / Ephemeral StateApp State
Digunakan satu widgetDigunakan banyak bagian aplikasi
Biasanya sederhanaDapat lebih kompleks
Cocok dengan setState()Sering membutuhkan pola state management
Contoh toggle passwordContoh status login
Contoh selected tabContoh shopping cart
Contoh checkbox lokalContoh user preferences

Namun ini bukan aturan absolut.

Flutter sendiri menekankan bahwa tidak ada batas universal yang selalu benar antara ephemeral state dan app state. Sebuah state dapat berubah kategori ketika kebutuhan aplikasi berkembang.

Lifting State Up

Kadang state awalnya berada di satu widget flutter, tetapi kemudian dibutuhkan oleh widget lain.

Misalnya:

Parent
├── ProductList
└── CartSummary

Keduanya membutuhkan informasi:

cartItems

Daripada masing-masing memiliki state yang berbeda:

ProductList
  └── cartItems

CartSummary
  └── cartItems

lebih baik state tertentu dinaikkan ke parent:

Parent
└── cartItems
    ├── ProductList
    └── CartSummary

Konsep ini sering disebut: lifting state up.

Flutter juga menggunakan pola ini dalam pembahasan state management sederhana.

Masalah Prop Drilling

Jika aplikasi semakin besar, data dapat harus melewati banyak constructor.

Contoh:

App
 ↓
Home
 ↓
Dashboard
 ↓
ProductSection
 ↓
ProductCard

Jika semua membutuhkan data yang sama, Anda mungkin akhirnya melakukan:

App(
  user: user,
  child: Home(
    user: user,
    child: Dashboard(
      user: user,
      child: ProductSection(
        user: user,
      ),
    ),
  ),
)

Untuk aplikasi kecil, hal ini mungkin masih dapat diterima.

Baca juga:  Roadmap Belajar Flutter dari Nol Sampai Siap Kerja

Tetapi pada aplikasi yang lebih kompleks, pendekatan tersebut dapat membuat kode sulit dikelola. Di sinilah state management mulai diperlukan.

Apa Itu State Management?

State management adalah cara aplikasi:

  1. menyimpan state,
  2. mengubah state,
  3. membagikan state,
  4. memberi tahu UI ketika state berubah.

Secara sederhana:

User Action
    ↓
State berubah
    ↓
Notifier / Controller
    ↓
UI mengetahui perubahan
    ↓
Widget rebuild

Flutter menyediakan beberapa pendekatan state management, mulai dari setState, ValueNotifier, InheritedWidget, hingga berbagai package dan pola arsitektur.

Tidak ada satu solusi yang wajib digunakan untuk semua aplikasi.

Mengapa Tidak Langsung Menggunakan State Management Package?

Pertanyaan ini sering muncul:

“Kalau nanti menggunakan Provider atau Riverpod, mengapa harus belajar setState?”

Karena memahami setState membantu Anda memahami dasar reactive UI.

Sebelum menggunakan:

Provider
Riverpod
Bloc
Cubit
GetX
dan lainnya

Anda sebaiknya memahami:

State
↓
Perubahan state
↓
UI rebuild

Jika konsep tersebut belum dipahami, package state management justru dapat terasa seperti sekumpulan kode yang harus dihafalkan.

Mengenal ChangeNotifier

Salah satu pendekatan yang masih digunakan dalam ekosistem Flutter adalah ChangeNotifier.

ChangeNotifier merupakan class dari Flutter SDK yang dapat memberi tahu listener ketika data berubah melalui:

notifyListeners();

Contoh sederhana:

class CounterModel extends ChangeNotifier {
  int count = 0;

  void increment() {
    count++;
    notifyListeners();
  }
}

Ketika:

count++;

state berubah.

Kemudian:

notifyListeners();

memberi sinyal kepada listener bahwa UI perlu merespons perubahan tersebut.

Mengenal Provider

provider merupakan salah satu package yang digunakan untuk membantu menyediakan dan mengakses state dalam widget tree.

Dokumentasi Flutter menggunakan provider sebagai salah satu contoh pendekatan state management sederhana dan menjelaskan konsep seperti:

  • ChangeNotifier
  • ChangeNotifierProvider
  • Consumer

Contoh instalasi:

flutter pub add provider

Kemudian:

import 'package:provider/provider.dart';

Contoh sederhana:

ChangeNotifierProvider(
  create: (context) => CounterModel(),
  child: const MyApp(),
)

Kemudian widget yang membutuhkan state dapat menggunakan Consumer.

Consumer<CounterModel>(
  builder: (context, counter, child) {
    return Text(
      '${counter.count}',
    );
  },
)

Ketika:

counter.increment();

memanggil:

notifyListeners();

widget yang mendengarkan perubahan tersebut dapat dibangun kembali.

Apakah Provider Wajib Digunakan?

Tidak.

Ini penting.

Flutter tidak mengharuskan developer menggunakan provider.

Dokumentasi Flutter mencantumkan beberapa pendekatan state management dan menjelaskan bahwa pemilihan pendekatan bergantung pada kebutuhan aplikasi, kompleksitas, pengalaman tim, dan faktor lainnya.

Di ekosistem Flutter juga terdapat pendekatan seperti:

setState
ValueNotifier
ChangeNotifier
Provider
Riverpod
BLoC / Cubit
dan lainnya

Pada tahap ini, tujuan kita bukan memilih satu package sebagai “yang paling benar”. Tujuannya adalah memahami mengapa state management diperlukan.

Navigation dan State Saling Berkaitan

Navigation dan state management sering bekerja bersama.

Contoh aplikasi e-commerce:

Home
 ↓
Product Detail
 ↓
Add to Cart
 ↓
Cart
 ↓
Checkout

State:

cartItems

harus tetap tersedia ketika pengguna berpindah halaman.

Jika state hanya berada di widget Product Detail:

Product Detail
    ↓
cartItems

ketika halaman ditutup, state tersebut mungkin tidak lagi berada di tempat yang tepat untuk digunakan oleh halaman Cart.

Karena itu, state yang digunakan banyak bagian aplikasi perlu ditempatkan pada scope yang sesuai.

Contoh Alur Aplikasi

Bayangkan aplikasi toko sederhana.

1. Home

Product A
Product B
Product C

2. User memilih Product A

Home
 ↓
Product Detail

3. User menekan Add to Cart

Product Detail
 ↓
cartItems berubah

4. User membuka Cart

Cart
 ↓
menampilkan Product A

Secara konseptual:

             ┌───────────────┐
             │  App State    │
             │   Cart Items  │
             └───────┬───────┘
                     │
          ┌──────────┴─────────┐
          ↓                    ↓
     Product Detail          Cart
          │                    │
          └── Navigation ──────┘

Inilah alasan navigation dan state management mulai dipelajari bersama.

Contoh Mini Project: Counter + Navigation

Mari gabungkan navigation dan state lokal.

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int counter = 0;

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              'Counter: $counter',
              style: const TextStyle(
                fontSize: 24,
              ),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: increment,
              child: const Text('Tambah'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) => DetailPage(
                      counter: counter,
                    ),
                  ),
                );
              },
              child: const Text('Lihat Detail'),
            ),
          ],
        ),
      ),
    );
  }
}

Halaman detail:

class DetailPage extends StatelessWidget {
  const DetailPage({
    required this.counter,
    super.key,
  });

  final int counter;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Detail'),
      ),
      body: Center(
        child: Text(
          'Nilai counter: $counter',
        ),
      ),
    );
  }
}

Contoh tersebut memperlihatkan tiga konsep:

State
 ↓
setState()
 ↓
UI berubah

dan:

Navigator.push()
 ↓
DetailPage

serta:

Passing data
 ↓
counter
 ↓
DetailPage

Ini adalah dasar yang sangat penting sebelum masuk ke aplikasi yang lebih kompleks.

Kesalahan Umum Saat Belajar Navigation

1. Semua halaman langsung dibuat menggunakan named routes

Named routes memang mudah dipahami, tetapi dokumentasi Flutter saat ini tidak merekomendasikannya untuk sebagian besar aplikasi. Untuk kebutuhan sederhana, gunakan Navigator dan MaterialPageRoute; untuk routing kompleks, pertimbangkan go_router atau pendekatan Router.

2. Tidak memahami stack

Jika belum memahami:

push
pop

navigation akan terasa membingungkan.

3. Menggunakan terlalu banyak navigation logic dalam widget

Ketika aplikasi semakin besar, navigation sebaiknya memiliki struktur yang jelas.

4. Tidak memikirkan deep linking

Untuk aplikasi web atau aplikasi yang harus membuka screen tertentu melalui URL, kebutuhan routing menjadi lebih kompleks. Flutter merekomendasikan Router atau package routing seperti go_router untuk kebutuhan seperti ini.

Baca juga:  Database Flutter: SQLite, Local Storage, dan CRUD untuk Pemula

Kesalahan Umum Saat Belajar State Management

1. Semua state dimasukkan ke satu StatefulWidget

Ini mungkin mudah di awal.

Namun semakin besar aplikasi:

HomePage
├── 500 lines
├── state 1
├── state 2
├── state 3
├── state 4
└── state 5

akan sulit dipelihara.

2. Menggunakan package terlalu cepat

Jangan menginstal state management package hanya karena melihat developer lain menggunakannya.

Pahami masalah yang ingin diselesaikan terlebih dahulu.

3. Menganggap setState buruk

setState() bukan metode yang salah.

Untuk state lokal sederhana, setState() justru merupakan pendekatan yang sesuai. Flutter secara eksplisit mencantumkannya sebagai pendekatan untuk widget-specific ephemeral state.

4. Semua state dianggap app state

Tidak semua variabel harus masuk ke global state.

Contoh:

isPasswordVisible

biasanya tidak perlu menjadi global state.

Pola Belajar State Management yang Disarankan

Untuk pemula, urutannya sebaiknya:

1. StatefulWidget
       ↓
2. setState()
       ↓
3. Local State
       ↓
4. Passing Data
       ↓
5. Lifting State Up
       ↓
6. App State
       ↓
7. ChangeNotifier
       ↓
8. Provider / pendekatan lain
       ↓
9. Architecture

Jangan melompat langsung ke tahap terakhir.

Dengan memahami dasar terlebih dahulu, Anda akan lebih mudah memahami mengapa sebuah state management architecture diperlukan.

Latihan Level 7

Sekarang buat aplikasi sederhana dengan tiga halaman:

Home
 ↓
Product List
 ↓
Product Detail
Home

Tampilkan:

My Store

[ Lihat Produk ]

Ketika tombol ditekan:

Home
 ↓
Product List
Product List

Tampilkan:

Laptop
Smartphone
Keyboard
Mouse

Ketika pengguna memilih Laptop:

Product List
 ↓
Product Detail

Kirim:

nama
harga
deskripsi

ke halaman detail.

Product Detail

Tampilkan:

Laptop

Harga:
Rp10.000.000

Deskripsi:
Laptop untuk developer.

[ Tambah ke Keranjang ]

Ketika tombol ditekan, ubah state:

cartCount++

Kemudian buat indikator jumlah keranjang.

Tantangan Tambahan

Setelah project dasar selesai, tambahkan:

Challenge 1 — Counter

Buat jumlah produk:

-
 1
+

Gunakan:

setState()
Challenge 2 — Favorite

Tambahkan tombol:

♡

Ketika ditekan:

♡ → ♥

Gunakan state lokal.

Challenge 3 — Passing Data

Kirim object product dari:

ProductList

ke:

ProductDetail
Challenge 4 — Return Data

Buat halaman pemilihan kategori:

Flutter
Dart
Firebase

Setelah user memilih:

CategoryPage
      ↓
return category
      ↓
ProductPage
Challenge 5 — Shared State

Buat CartModel menggunakan ChangeNotifier.

Contoh sederhana:

class CartModel extends ChangeNotifier {
  final List<String> items = [];

  void addItem(String item) {
    items.add(item);
    notifyListeners();
  }
}

Kemudian gunakan provider untuk menyediakan state tersebut kepada widget yang membutuhkan.

Dokumentasi Flutter menggunakan pola ChangeNotifier + ChangeNotifierProvider + Consumer sebagai salah satu contoh sederhana untuk state management bersama.

Checklist Setelah Menyelesaikan Level 7

Pastikan Anda sudah memahami:

  • Apa itu navigation Flutter
  • Apa itu Navigator
  • Apa itu Route
  • Cara menggunakan Navigator.push()
  • Cara menggunakan Navigator.pop()
  • Konsep navigation stack
  • Cara menggunakan MaterialPageRoute
  • Cara berpindah antar halaman
  • Cara passing data antar halaman
  • Cara mengembalikan data dari halaman
  • Konsep named routes
  • Keterbatasan named routes
  • Dasar go_router
  • Apa itu state
  • Apa itu local/ephemeral state
  • Apa itu app state
  • Perbedaan local state dan app state
  • Cara menggunakan setState()
  • Konsep lifting state up
  • Mengapa shared state diperlukan
  • Apa itu ChangeNotifier
  • Fungsi notifyListeners()
  • Konsep dasar Provider
  • Hubungan navigation dan state

Navigation dan State Management dalam Roadmap Flutter

Jika kita melihat perjalanan sampai saat ini:

Level 0 - Memahami Flutter
        ↓
Level 1 - Dasar Pemrograman
        ↓
Level 2 - Dart
        ↓
Level 3 - Setup Environment
        ↓
Level 4 - Struktur Project
        ↓
Level 5 - Widget
        ↓
Level 6 - Layout & Responsive UI
        ↓
Level 7 - Navigation & State Management

Terlihat bahwa setiap level memiliki fungsi yang berbeda.

Level 4 membuat Anda memahami tempat kode berada. Level 5 mengajarkan komponen UI. Level 6 layout dan responsive UI Flutter mengajarkan cara menyusun UI secara responsif. Level 7 mulai mengajarkan bagaimana aplikasi berpindah halaman dan merespons perubahan data.

Setelah tahap ini, kita mulai memiliki aplikasi yang jauh lebih menyerupai aplikasi nyata.

Apa yang Dipelajari Setelah Level 7?

Sampai tahap ini, aplikasi masih menggunakan data lokal atau data sederhana.

Contohnya:

Product
User
Cart
Counter

Tetapi aplikasi nyata membutuhkan data dari server.

Misalnya:

Flutter App
     ↓
Internet
     ↓
REST API
     ↓
Backend Server
     ↓
Database

Contohnya aplikasi membutuhkan:

GET /products
POST /login
GET /profile
POST /orders

Pada titik tersebut, kita membutuhkan kemampuan networking.

Karena itu, level berikutnya adalah: Level 8 — REST API Flutter.

Pada Level 8, kita akan mulai belajar bagaimana Flutter berkomunikasi dengan server melalui HTTP dan REST API.

Materinya akan mencakup:

  • konsep API
  • HTTP
  • GET
  • POST
  • PUT
  • DELETE
  • request dan response
  • JSON
  • parsing JSON
  • model Dart
  • serialization
  • package HTTP
  • loading state
  • error state
  • API authentication dasar
  • menampilkan data API ke widget
  • membuat CRUD sederhana

Dengan demikian, alurnya berkembang menjadi:

UI
 ↓
Navigation
 ↓
State
 ↓
REST API
 ↓
Server
 ↓
Database

Ini merupakan tahap penting karena mulai menghubungkan frontend Flutter dengan dunia backend.

Kesimpulan

Navigation dan State Management merupakan dua konsep yang membuat aplikasi Flutter mulai terasa hidup.

Navigation memungkinkan pengguna berpindah:

Home
 ↓
Detail
 ↓
Checkout

Sedangkan state management memungkinkan UI merespons perubahan:

User Action
 ↓
State berubah
 ↓
UI diperbarui

Untuk navigation dasar, pahami terlebih dahulu:

Navigator
Route
push()
pop()
MaterialPageRoute

Flutter menggunakan Navigator sebagai stack route untuk navigation imperatif sederhana. Untuk aplikasi dengan kebutuhan routing dan deep linking yang lebih kompleks, Flutter saat ini merekomendasikan pendekatan Router atau package seperti go_router, sementara named routes tidak direkomendasikan untuk sebagian besar aplikasi.

Untuk state management, jangan langsung mengejar package.

Mulailah dengan:

State
 ↓
StatefulWidget
 ↓
setState()
 ↓
Local State

Kemudian pahami:

Lifting State Up
 ↓
App State
 ↓
ChangeNotifier
 ↓
Provider / pendekatan state management lainnya

setState() tetap merupakan pilihan yang tepat untuk state lokal sederhana, sedangkan state yang digunakan oleh banyak bagian aplikasi biasanya membutuhkan pendekatan yang lebih terstruktur. Flutter sendiri tidak menetapkan satu solusi state management universal; pilihan bergantung pada kebutuhan dan kompleksitas aplikasi.

Yang paling penting adalah memahami konsep di baliknya.

Jangan sekadar menghafalkan:

Navigator.push()

atau:

setState(() {});

Pahami apa yang terjadi:

Navigator
    ↓
mengatur perjalanan antar halaman

State
    ↓
menyimpan kondisi aplikasi

setState()
    ↓
memberi tahu Flutter bahwa state lokal berubah

State Management
    ↓
mengatur state yang lebih luas dan kompleks

Jika konsep tersebut sudah dikuasai, Anda sudah siap masuk ke tahap berikutnya: menghubungkan aplikasi Flutter dengan REST API dan data dari server.

Selanjutnya kita masuk ke Level 8 — REST API Flutter, ketika aplikasi mulai mengambil dan mengirim data ke backend.

Bagikan

Tinggalkan komentar

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *

Artikel Terkait
database flutter
CodingFlutter

Database Flutter: SQLite, Local Storage, dan CRUD untuk Pemula

Pelajari database Flutter dan local storage dari nol, mulai dari SQLite, shared_preferences,...

rest api flutter
CodingFlutter

REST API Flutter: Panduan HTTP, JSON, dan Pengolahan Data

Pelajari REST API Flutter dari nol, mulai dari HTTP request, GET, POST,...

layout responsive ui flutter
CodingFlutter

Layout dan Responsive UI Flutter: Panduan untuk Pemula

Pelajari layout dan responsive UI Flutter dari nol, mulai dari constraints, Row,...

menguasai widget flutter
CodingFlutter

Menguasai Widget Flutter: Jenis, Fungsi, dan Contohnya untuk Pemula

Pelajari widget Flutter dari nol, mulai dari widget tree, StatelessWidget, StatefulWidget, BuildContext,...