Passing Data antar Halaman
Kirim objek/data ke halaman tujuan lewat constructor.
Kenapa Passing Data Itu Penting?
Hampir tidak ada halaman yang berdiri sendiri. Halaman detail perlu tahu produk mana yang diklik, halaman checkout perlu tahu isi keranjang, halaman edit profil perlu data user saat ini. Flutter tidak otomatis memberi tahu halaman tujuan tentang konteks; data harus dikirim eksplisit saat navigasi. Cara paling sederhana dan paling type-safe adalah lewat constructor halaman tujuan, karena compiler ikut menjaga kebenarannya.
Data Lewat Constructor
Jadikan data sebagai parameter wajib (required) di halaman tujuan:
class HalamanDetail extends StatelessWidget {
final String namaProduk;
final int harga;
const HalamanDetail({
super.key,
required this.namaProduk,
required this.harga,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(namaProduk)),
body: Center(child: Text('Harga: Rp$harga')),
);
}
}Mengirimnya Saat Push
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HalamanDetail(
namaProduk: 'Kopi Susu',
harga: 15000,
),
),
);Compiler menjamin semua parameter required terisi dengan tipe yang benar. Salah tipe langsung merah di editor, bukan crash misterius saat aplikasi berjalan. Ini keunggulan terbesar dibanding mengirim data lewat Map atau arguments.
Naik Level: Kirim Object Model
Untuk data kompleks, kirim satu object model, bukan pecahan field satu per satu:
class Produk {
final String nama;
final int harga;
final String fotoUrl;
const Produk({
required this.nama,
required this.harga,
required this.fotoUrl,
});
}
// di daftar produk, saat item diklik:
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => HalamanDetailProduk(produk: produk),
),
);
}Halaman detail menerima final Produk produk; lalu bebas memakai produk.nama, produk.harga, dan produk.fotoUrl. Menambah field baru (misalnya rating atau stok) tidak mengubah signature navigasi di file mana pun. Kode tetap rapi walau model bertambah besar.
Catatan teknis: Jadikan field model
finalagar immutable. Halaman tujuan tidak boleh diam-diam mengubah data milik halaman pengirim. Kalau butuh hasil edit, kembalikan lewatNavigator.pop(context, produkBaru)seperti pada modul pop-data.
Edge Cases & Best Practices
- Data boleh null? Kalau halaman bisa dibuka tanpa data (mode tambah versus mode edit), jadikan parameter nullable (
Produk?) dan tangani kedua cabang dibuild, jangan asal pakai!. - List besar: jangan kirim ulang seluruh list kalau hanya satu item yang dibutuhkan; kirim itemnya saja, atau kirim ID lalu ambil ulang dari sumber data di halaman tujuan.
- Named route: tidak bisa lewat constructor, jadi pakai
arguments(lihat modul named route). Kelemahannya: cast manual dan tidak type-safe, jadi hanya untuk kasus sederhana. - Data berubah setelah dikirim: constructor hanya snapshot satu kali. Kalau halaman tujuan harus reaktif terhadap perubahan data, pakai state management, bukan constructor.
Kapan Jangan Pakai Constructor
Constructor ideal untuk data yang dikirim sekali dan dipakai sekali di antara dua halaman. Kalau data yang sama dibutuhkan lima halaman berbeda (data user, tema aplikasi, keranjang), passing manual terus-menerus menjadi melelahkan dan rapuh: satu halaman lupa meneruskan, rantai langsung putus. Di titik itu, pindah ke Provider atau Riverpod agar data tersedia global tanpa oper estafet.
Tantangan
Detail produk
Buat HalamanDetail yang menerima nama dan harga. Dari daftar produk, kirim data produk yang diklik ke halaman detail.