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.
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 State | App State |
|---|---|
| Digunakan satu widget | Digunakan banyak bagian aplikasi |
| Biasanya sederhana | Dapat lebih kompleks |
Cocok dengan setState() | Sering membutuhkan pola state management |
| Contoh toggle password | Contoh status login |
| Contoh selected tab | Contoh shopping cart |
| Contoh checkbox lokal | Contoh 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.
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:
- menyimpan state,
- mengubah state,
- membagikan state,
- 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:
ChangeNotifierChangeNotifierProviderConsumer
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.
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.
- app state Flutter
- belajar Flutter
- belajar Flutter dari nol
- belajar Flutter untuk pemula
- belajar navigation Flutter
- ChangeNotifier Flutter
- Flutter Developer
- local state Flutter
- MaterialPageRoute Flutter
- navigasi antar halaman Flutter
- navigation Flutter
- passing data Flutter
- Provider Flutter
- Route Flutter
- setState Flutter
- state management Flutter
- StatefulWidget Flutter
- tutorial Flutter
Tinggalkan komentar