Boolean: Bisa Jadi Bukan Teman Baikmu
Studi Kasus
Singkat cerita, Jum’at kemarin salah satu rekan kerja saya sedang membuat fitur “read more” untuk konten dengan tinggi lebih dari 300px (tidak ada tombol “read more” jika kurang). Ketika tombol tersebut di-click, seluruh isi konten baru akan ditampilkan.
Cukup jelas. Namun ada masalah baru: setHasReadMoreBtn(true)
dijalankan setelah render. Artinya, jika tinggi content ternyata melebihi 300px, flash of content pun kemungkinan terjadi: awalnya user melihat seluruh isi content, lalu sepersekian detik kemudian tombol “read more” baru muncul
Ngakalinnya, jangan tampilkan konten ke user sebelum tinggi konten diketahui.
Masalah selesai. Tapi entah kenapa ada sesuatu yang mengganjal. It feels hacky. Masa iya harus butuh 3 buah state hanya untuk membuat fitur se-simple ini. Belum lagi, dengan kombinasi tiga buah boolean saja, ada banyak kemungkinan yang bisa terjadi. Beberapa diantaranya justru tidak valid.
Kombinasi | Validitas & Penjelasan |
---|---|
hasReadMoreBtn ✅isExpanded ✅isReady ✅ | Valid. State ini terjadi ketika tinggi konten melebihi 300px, dan user sudah meng-klik tombol “read more” |
hasReadMoreBtn ✅isExpanded ✅isReady ❌ | Tidak valid. Bagaimana mungkin isExpanded sudah bernilai true sedangkan isReady masih bernilai false |
hasReadMoreBtn ✅isExpanded ❌isReady ✅ | Valid. State ini terjadi ketika konten dengan tinggi >300px sudah tersedia namun user belum meng-klik tombol “read more” |
hasReadMoreBtn ✅isExpanded ❌isReady ❌ | Valid. State ini terjadi ketika konten dengan tinggi >300px belum ditampilkan ke layar |
hasReadMoreBtn ❌isExpanded ✅isReady ✅ | Tidak valid. isExpanded = true (tombol “read more” ketika sudah di-click) hanya mungkin terjadi bila hasReadMoreBtn juga bernilai true |
hasReadMoreBtn ❌isExpanded ✅isReady ❌ | Tidak valid. Sama seperti di atas |
hasReadMoreBtn ❌isExpanded ❌isReady ✅ | Valid. konten sudah disajikan dan tingginya tidak melebihi 300px |
hasReadMoreBtn ❌isExpanded ❌isReady ❌ | Valid. konten belum disajikan dan tingginya tidak melebihi 300px |
Pasti ada cara lain yang jauh lebih simple.
Solusi
Setelah me-review ulang behavior fitur ini dengan secarik kertas untuk dicorat-coret, saya mendapati bahwa sebenarnya requirement-nya cukup simple:
- Sembunyikan konten sampai tinggi konten diketahui (hidden)
- Jika tinggi konten kurang dari 300px, tampilkan seluruh isi konten (expanded)
- Jika lebih,
- konten bisa di-expand dengan tombol “read more” (expandable)
- Setelah tombol “read more” di-klik, tampilkan seluruh isi konten (expanded)
Dari list ini terlihat bahwa secara behavior, konten hanya bisa memiliki salah satu dari ketiga state berikut: Hidden, Expandable, atau Expanded. Kata kuncinya “atau”. As you might have guessed, solusi terbaik untuk masalah ini adalah dengan memodelkannya menggunakan union.
Dengan pendekatan ini, kita telah mengeliminasi kemungkinan-kemungkinan state yang tidak valid sekaligus meningkatkan code readability. Kita bisa belajar dari kasus ini bahwa memang mudah memodelkan suatu behavior dengan boolean, namun saya rasa masih ada cara lain yang lebih tepat. Bila dalam memecahkan masalah ada dua atau lebih boolean yang terlibat yang saling berkaitan, mundurlah selangkah dan mulai pahami kembali requirement dari fitur yang ingin diimplementasi. Ambillah secarik kertas dan tulis semua kondisi yang mungkin muncul. Mungkin dengan enum atau union biasa solusimu jadi lebih simple 😉
Oh ya, saya sampai lupa ternyata saya juga pernah mengulas kasus serupa di artikel yang lain: Tentang Loading State… 🙃
Kesimpulan
Boolean bukanlah segalanya. Bahkan mungkin eksistensinya bisa tergantikan dengan enum atau untagged union.
Siapa yang tahu? Setidaknya, sudah ada yang memodelkannya dengan union.
Sebagai penutup, video ini wajib ditonton bagi kamu yang ingin lebih mendalami tentang pemodelan business requirement ke dalam code:
Stay well, my friend!