Stateful dan Stateless Widget

Stateful dan Stateless
Dalam Pemrograman Mobile Flutter


Sebelumnya, di artikel Struktur Dasar Projek Flutter dijelaskan dengan analogi atau perumpamaan rumah. Sebuah rumah dibangun dengan kewajiban ada pondasi berupa tanah sebagai pijakan bangunan dan lantai, kerangka, dekorasi serta ruangan dan isi-isinya.

Begitulah sebuah projek flutter

Pada bagian pertama
Ada import dan main sebagai dasar pondasi. Fungsi main ini menampung widget kerangka aplikasi atau bagian kerangka rumah. Kerangka dalam flutter ini adalah MaterialApp(). Kerangka ini dibangun dengan jenis StatelessWidget.

Setelah kerangka aplikasi / kerangka rumah dibuat, di dalamnya diberikan isi atau beberapa ruangan yang akan digunakan/dipakai/berkegiatan. Isi dari kerangka ini diletakkan/dipanggil dengan home:
Terlihat dalam contoh projek dinamakan dengan MyHomePage()


MyHomePage() ini yang nantinya berisi berbagai hal untuk isi dari aplikasi/rumah, berbagai isi dalam flutter ini ditampung dengan menggunakan widget Scaffold(). Isi dari kerangka aplikasi ini dibangun dengan jenis StatefulWidget.

Apa sih StatelessWidget dan StatefulWidget ?
Mari kita bahas dengan konsep dalam kehidupan nyata...

StatelessWidget merupakan sebuah kondisi aplikasi yang tidak memiliki state atau kondisi. Selama aplikasi berjalan, kondisinya tetap. Layaknya sebuah rumah, kerangka rumah itu hampir tidak pernah berubah. Bila sejak awal dibangun dengan tiang berada di tengah, maka tidak mungkin 1 jam kemudian dipindah ke sisi kanan/kiri. Atau tiba-tiba menggeser posisi tembok.

Maka dari itu kerangka aplikasi flutter ( atau halaman-halaman yang kondisinya tetap ), harus dibuat dengan widget jenis StatelessWidget. Contohnya seperti halaman log in, secara ringkas hampir jarang ada aplikasi yang halaman log in dibuat berubah setiap waktu. Tiba-tiba tulisan berubah, dari log in menjadi masuk atau beberapa detik kemudian berubah menjadi sign in. Lainnya misal tombolnya berganti warna atau mengecil ukurannya.

Seperti penjelasan diatas, kode dalam flutter kita analogikan dengan sebuah rumah. Kerangka rumah atau pondasi tidak mungkin ada perubahan tiba-tiba. Kesimpulannya kerangka aplikasi/rumah bersifat tetap, maka dari itu menggunakan StatelessWidget.

Sedangkan StatefulWidget adalah sebuah kondisi yang mengalami perubahan. Isi dalam kerangka rumah merupakan hal yang akan mengalami perubahan, seperti pindah posisi dari ruang satu ke ruang lain. Begitu pula di aplikasi. Yang bisa ada perubahan seperti data-data yang tampil pada halaman profil, gambar atau nama. Kemudian angka dalam aplikasi jam/kalender, pilihan pembayaran dari merchant satu ke lainnya. Hal-hal ini merupakan sebuah perubahan.

Dua jenis widget ini, tidak memiliki perbedaan visual. Namun memiliki perbedaan dari segi penggunaan resource. Bila banyak menggunakan stateful akan mengakibatkan penggunaan semakin besar.

Jadi, dalam membangun aplikasi bergerak ( mobile app ) dengan flutter harus jeli menentukan widget dibuat dengan StatefulWidget atau StatelessWidget.



Implementasi Widget

Stateful
Widget stateful merupakan class widget yang dibangun dengan pewarisan ( inheritance ) dari induk Stateful, artinya:
  1. class tersebut adalah sebuah class baru yang turunan ( subclass ).
  2. Karena dia extends StatefulWidget, otomatis bisa menggunakan semua properti, method dan perilaku yang ada di dalam StatefulWidget.
  3. Bisa menambahkan atau menimpa (override) method tertentu, seperti createState().

Perhatikan baris kode berikut, mengubah ukuran font
import 'package:app_pertama/halamanKedua.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: AppStateful());
  }
}

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

  @override
  State<AppStateful> createState() => _AppStatefulState();
}

class _AppStatefulState extends State<AppStateful> {
  int ukuranFont = 12;

  void setUkuran() {
    setState(() {
      ukuranFont = ukuranFont + 5;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(backgroundColor: Colors.blue, title: Text("Aplikasiku")),
      body: Column(
        children: [
          Center(
            child: Text(
              "Ahmad Istakim",
              style: TextStyle(fontSize: ukuranFont.toDouble()),
            ),
          ),
          Center(
            child: Text("Ukuran font sekarang : $ukuranFont"),
          ),
          ElevatedButton(
            child: Text("Ubah Ukuran"),
            onPressed: () {
              setUkuran();
            },
          ),
          ElevatedButton(
            child: Text("Lihat Ukuran Font"),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => HalamanKedua(
                    ukuranFont: ukuranFont
                  )
                )
              );
            },
          ),
        ],
      ),
    );
  }
}


Pertama, di bagian Scaffold membuat UI 

  1. Teks di tengah dengan tulisan "Ahmad Istakim" dan menampilkan ukuran font.
  2. Tombol untuk mengubah ukuran.
  3. Tombol untuk mengirim ukuran ke halaman lain.
Pada bagian atas sebelum @override Scaffold, buat variabel untuk menentukan / menampung ukuran font dan sebuah fungsi ( method ) yang akan menambah nilai ukuran font setiap kali dipanggil.

Fungsi setUkuran(), akan dipanggil setiap tombol Ubah ukuran di klik ( onPressed )


Jalankan untuk di uji, flutter run
Dan lakukan klik berulang pada tombol "Ubah Ukuran"


Akan terjadi perubahan ( memperbesar ukuran teks "Ahmad Istakim" ) dan angka dari ukurannya
Inilah yang dinamakan dengan widget stateful, bisa terjadi atau mengakomodir perubahan pada UI maupun data.
 


Stateless
Stateless merupakan bentuk penyajian UI atau data yang sifatnya static. Tidak akan terjadi perubahan saat halaman tersebut selama halaman tidak ditutup. Stateless ini hanya menyajikan atau menampilkan, tidak bisa mengolah.

Contoh kasus, di atas ukuran font dikirimkan ke halaman lain melalui tombol "Lihat Ukuran Font"

Tentunya, sudah dibuat terlebih dahulu file baru dengan isinya widget Stateless


import 'package:flutter/material.dart';

class HalamanKedua extends StatelessWidget {
  HalamanKedua({super.key, required this.ukuranFont});
  int ukuranFont;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          children: [
            Text("Ukuran font sekarang : $ukuranFont"),
          ],
        ),
      ),
    );
  }
}

Widget stateless tidak bisa menampung atau mengakomodir state, seperti stateful
Kalaupun dipaksan dengan menambahkan state, akan muncul error

The declaration 'setState' isn't referenced.
Try removing the declaration of 'setState'.

Karena memang tidak didukung dalam stateless.



int ukuranFont adalah nilai final yang diterima dari tombol halaman sebelumnya, diterima sebagai nilai parameter wajib required this.ukuranFont.

required inilah yang mewajibkan mengisi paramter pada pemanggilan class di Navigator.push tombol "Lihat Ukuran Font"


Jalankan kembali dan lihat hasilnya
flutter run

Cobah untuk kembali ke halaman pertama, klik ubah ukuran
Dan lihat nilainya dengan tombol "Lihat Ukuran Font"




Perubahan di widget stateless hanya bisa jika halaman ditutup. Tidak bisa langsung saat UI aktif.
Semoga bermanfaat




Posting Komentar

0 Komentar