State: Bukan Cuma Data, Tapi Ingatan Sistem
State: Bukan Cuma Data, Tapi Ingatan Sistem
Dalam bab-bab sebelumnya, kita mungkin sudah sering menyentuh soal bug dan logika program; sekarang mari kita selami satu konsep dasar yang jika dipahami setengah-setengah, justru menjadi biang kerok dari banyak masalah itu: state.
Saya pernah punya teman, sebut saja Rio, yang frustrasi berat dengan aplikasi buatannya. “Ini programnya nggak stabil, Haj,” keluhnya sambil menatap layar penuh kode yang, kalau di-scroll, kayak mantra panjang yang bikin pusing. “Kadang tombol ‘Simpan’ bisa diklik, kadang nggak. Data yang udah di-input lenyap gitu aja. Gue udah cek logika if-else-nya beratus kali, nggak ada yang salah!”
Saya minta izin lihat kodenya. Dan di sana, seperti dugaan, tersebar variabel-variabel global—isEditing, currentData, formSubmitted—yang diubah-ubah dari sembarang tempat. Di satu fungsi, isEditing diset true. Di fungsi lain, dua ratus baris bawah, tanpa alasan yang jelas, tiba-tiba diset false. currentData terkadang jadi objek, terkadang jadi null, tergantung urutan klik user yang sulit ditebak. Program Rio itu seperti orang yang punya ingatan jangka pendek yang parah, ditambah lagi ingatannya bisa diubah oleh siapa saja, kapan saja, tanpa izin. State-nya kacau. Chaos.
Ini kesalahan klasik. Kita—saya juga pernah—sering menganggap state itu cuma “data yang lagi dipake”. Sebuah wadah. Seperti tas ransel yang kita bawa. Isinya bisa kita ambil, kita ganti, kita buang. Padahal, analogi itu salah kaprah. State itu bukan tas. State itu adalah ingatan lengkap tentang apa yang sedang terjadi pada sistem pada satu titik waktu tertentu. Ia bukan cuma “apa yang ada di dalam tas”, tapi juga “kenapa tas itu dibuka”, “siapa yang terakhir menyentuhnya”, “apakah kita sedang dalam perjalanan ke mana”, dan “apakah hujan di luar yang bisa bawa tas basah”.
Bayangkan sebuah lampu lalu lintas. Data mentahnya cuma tiga: merah, kuning, hijau. Tapi state-nya jauh lebih kompleks. Ia harus ingat warna apa yang sedang menyala, berapa detik lagi sebelum ganti, apakah sedang mode normal atau malam hari (yang cuma kuning kedap-kedip), apakah ada kendaraan darurat yang meminta prioritas. Jika sistem lampu lalu lintas cuma menyimpan “warna = hijau” tanpa mengingat konteks sisanya, maka saat malam tiba dan harus mode kedap-kedip, sistem itu akan kebingungan. Ia tidak punya ingatan bahwa ada aturan lain yang berlaku.
Di pemrograman, state yang buruk itu seperti punya teman sekamar yang ceroboh. Kamu taruh remote TV di meja. Lima menit kemudian, remote itu ada di bawah bantal. Kamu taruh susu di kulkas. Besok paginya, susu itu sudah di meja, hangat. Kamu tanya, “Eh, siapa yang pindahin remote? Siapa yang tinggalin susu?” Dia cuma bisa geleng-geleng, “Aku nggak tahu. Tadi ada yang masuk kali?” Hidup jadi tidak bisa diprediksi. Sistem dengan state yang dikelola asal-asalan persis seperti itu: tidak bisa diprediksi. Dan dalam dunia software, ketidakpastian adalah nama lain dari bug.
Lalu, di mana letak kesalahan asumsi yang paling umum?
Pertama, kita menganggap state itu pasif. Kita pikir state itu cuma tempat penyimpanan. Database, variabel, file. Tinggal baca dan tulis. Padahal, state itu aktif. Ia punya konsekuensi. Mengubah satu nilai state bisa memicu rangkaian kejadian lain (side effects) yang seperti efek domino. Misal, kamu set user.isLoggedIn = false. Itu bukan cuma mengubah boolean. Itu harusnya juga: membatalkan semua request yang sedang pending, mengosongkan keranjang belanja, mengalihkan halaman ke login, dan mengirim notifikasi ke server. Jika kamu cuma mengubah boolean-nya saja, sisa “ingatan” sistem tentang apa yang harus dilakukan setelah logout menjadi hilang. Jadilah bug.
Kedua, kita menganggap state itu tunggal dan global. Ini jebakan Rio tadi. Satu variabel untuk semua. Padahal, sistem yang baik seringkali perlu punya beberapa “ingatan” yang terpisah dan terisolasi. State untuk UI (apakah modal terbuka?), state untuk data bisnis (apa isi cart?), state untuk jaringan (sedang loading apa tidak?). Mencampurkannya adalah resep untuk kekacauan. Ibaratnya, kamu mencampur ingatan tentang resep masakan dengan ingatan tentang jadwal meeting. Hasilnya, kamu bisa jadi masak ayam dengan tambahan “reminder: rapat pukul 3”. Bukan rasa yang diharapkan.
Ketiga, dan ini yang paling halus: kita lupa bahwa state punya riwayat dan konteks. State bukanlah snapshot yang statis. Ia adalah titik dalam sebuah alur waktu. Sebuah transaksi e-commerce punya state: dari ‘keranjang’, jadi ‘checkout’, jadi ‘menunggu pembayaran’, jadi ‘diproses’, jadi ‘dikirim’. Setiap state itu sah hanya jika state sebelumnya valid. Kamu tidak bisa langsung berada di state ‘dikirim’ tanpa pernah melalui ‘menunggu pembayaran’. Mengabaikan riwayat ini—misal, karena bug atau hack—berarti merusak logika bisnis yang mendasar. Sistem mungkin tetap jalan, tapi jalannya salah arah.
Jadi, bagaimana cara mengelola “ingatan” sistem ini dengan benar? Tidak ada jawaban tunggal, tapi prinsipnya mirip seperti kita mengelola ingatan sendiri.
1. Beri batas yang jelas. Seperti kita punya “ingatan kerja” untuk hal yang sedang dikerjakan, dan “ingatan jangka panjang” untuk pengetahuan. Dalam kode, ini berarti memisahkan state lokal komponen (ingatan kerja) dengan state global aplikasi (ingatan jangka panjang). Dan jangan sembarangan mengakses satu sama lain.
2. Satu pintu masuk untuk mengubah. Ingatan kita bisa rusak jika terlalu banyak orang yang bilang versi cerita yang berbeda. Dalam sistem, perubahan state harus melalui satu mekanisme yang jelas—biasanya lewat fungsi atau metode khusus (action, mutation, reducer). Jangan biarkan sembarang baris kode bisa seenaknya mengubah isLoading = true. Itu seperti membiarkan orang asing masuk ke rumah dan mengganti letak furnitur sesuka hati.
3. Buat riwayatnya bisa dilacak (traceable). Saat terjadi bug, pertanyaan terbesar adalah: “State-nya jadi seperti ini gara-gara apa?” Jika setiap perubahan state dicatat (logged), atau bahkan dibuat immutable (tidak bisa diubah langsung, tapi harus diganti dengan salinan baru), maka kita bisa mundur dan melihat kronologinya. Seperti fitur “History” di Photoshop. Ini kerja ekstra di awal, tapi menyelamatkan berjam-jam debugging di kemudian hari.
Mengelola state dengan sadar juga berarti menerima sebuah fakwa: kompleksitas itu tidak hilang, ia cuma dipindah. Kamu tidak bisa menghilangkan kompleksitas logika dari aplikasi yang memang kompleks. Yang bisa kamu lakukan adalah memindahkan kompleksitas itu dari tempat yang berantakan (seperti tersebar di seluruh kode) ke tempat yang terkontrol (seperti state management pattern: Redux, Vuex, atau yang sederhana seperti custom hooks).
Di akhir, saya bantu Rio merapikan kodenya. Kami pindahkan semua state yang berserakan ke dalam sebuah objek tunggal yang jelas strukturnya. Lalu kami buat fungsi-fungsi khusus yang bertanggung jawab untuk mengubah state itu. Tidak ada lagi yang bisa mengubah state secara langsung. Harus lewat fungsi. Prosesnya seperti merapikan rumah yang berantakan: menyortir, memberi label, dan menetapkan tempat untuk setiap barang.
Hasilnya? Bug yang aneh-aneh itu berkurang drastis. Bukan karena kodenya jadi lebih singkat—justru tambah beberapa baris. Tapi karena sekarang sistem punya “ingatan” yang teratur. Saat tombol ‘Simpan’ disabled, kita tahu persis kenapa: karena state isSubmitting bernilai true, dan nilai itu hanya bisa diubah oleh satu fungsi yang bertanggung jawab memulai proses submit. Prediktabilitas meningkat. Kebugaran mental developer juga.
Pelajaran besarnya sederhana: sistem yang kita bangun adalah makhluk yang punya ingatan. Cara kita merancang ingatan itu akan menentukan apakah sistem itu tumbuh menjadi dewasa yang stabil, atau tetap menjadi anak kecil yang temperamental dan sulit ditebak.
Memahami bahwa state adalah ingatan yang hidup dan terus berubah, bukan sekadar tempat penyimpanan statis, adalah salah satu kerja sunyi yang membedakan sistem yang hanya jalan, dengan sistem yang benar-benar andal.
FAQ: Tanya Jawab Seputar State
Q: State itu sama dengan database, ya?
A: Tidak. Database adalah tempat penyimpanan persistensi. State adalah kondisi sistem di memori pada saat itu juga. Database bisa jadi sumber untuk mengisi state awal, tapi state bisa berisi hal yang tidak ada di database (contoh: “apakah dropdown ini terbuka?”).
Q: Kapan harus pakai state management kayak Redux? Ribet soalnya.
A: Saat state-mu mulai seperti benang kusut yang melibatkan banyak komponen yang tidak berhubungan langsung. Kalau cuma butuh ingatan dalam satu komponen (misal: nilai input form), state lokal cukup. Redux itu kayak papan pengumuman kantor yang besar—buat info yang harus diketahui banyak divisi. Jangan dipakai cuma buat catatan belanja pribadi.
Q> Kenapa bug karena state sering disebut “heisenbug”?
A> Karena seperti prinsip Ketidakpastian Heisenberg dalam fisika: begitu kamu mencoba mengamatinya (debug), perilakunya berubah. Misal, kamu console.log state, tiba-tiba bugnya hilang karena proses logging sedikit mengubah timing eksekusi. Itu ciri khas bug yang terkait timing dan perubahan state yang tidak terkelola.
Q> Apa analogi sehari-hari yang paling gampang untuk memahami state?
A> Coba lihat mesin ATM. State-nya: kartu sudah dimasukkan belum? PIN sudah benar? Saldo cukup? Transaksi yang dipilih apa? Uang sudah keluar belum? Jika kamu tekan “Batal” di tengah jalan, ATM harus ingat state mana yang harus dikembalikan (misal: mengeluarkan kartu, tanpa mengeluarkan uang). Kalau state-nya kacau, bisa-bisa uang keluar padahal kartu sudah dikembalikan. Ngeri kan?
Q> Apakah immutable state itu wajib?
A> Tidak wajib, tapi sangat, sangat disarankan. Bayangkan kamu punya dokumen. Lebih aman edit dengan “Save As” (bikin salinan baru) daripada menimpa file aslinya langsung. Jika salah, kamu masih punya versi lama. Immutable state memberikan jaminan predictability yang sama.
State: Not Just Data, But a System's Memory
In previous chapters, we've likely touched on bugs and program logic; now let's dive into a basic concept that, when half-understood, often becomes the root cause of many of those problems: state.
I once had a friend, let's call him Rio, who was deeply frustrated with an application he built. "This program is unstable, Haj," he complained, staring at a screen full of code that, when scrolled, looked like a long, dizzying incantation. "Sometimes the 'Save' button can be clicked, sometimes it can't. Inputted data just vanishes. I've checked the if-else logic hundreds of times, nothing's wrong!"
I asked to see his code. And there, as suspected, were scattered global variables—isEditing, currentData, formSubmitted—being changed from arbitrary places. In one function, isEditing is set to true. In another function, two hundred lines down, without clear reason, it's suddenly set to false. currentData sometimes is an object, sometimes null, depending on the user's unpredictable click sequence. Rio's program was like a person with severe short-term memory loss, whose memories could also be altered by anyone, anytime, without permission. Its state was chaotic. Chaos.
This is a classic mistake. We—I've been there too—often think of state as just "the data currently in use." A container. Like a backpack we carry. We can take things out, replace them, throw them away. That analogy is mistaken. State is not a bag. State is the complete memory of what is happening in the system at a specific point in time. It's not just "what's in the bag," but also "why the bag was opened," "who last touched it," "whether we're on our way somewhere," and "if it's raining outside which could get the bag wet."
Imagine a traffic light. Its raw data is just three things: red, yellow, green. But its state is far more complex. It must remember which color is currently lit, how many seconds until it changes, whether it's in normal mode or night mode (only blinking yellow), if there's an emergency vehicle requesting priority. If the traffic light system only stores "color = green" without remembering the rest of the context, then when night comes and it must switch to blinking mode, the system will be confused. It has no memory that another rule applies.
In programming, bad state is like having a careless roommate. You put the TV remote on the table. Five minutes later, it's under the pillow. You put milk in the fridge. The next morning, it's on the table, warm. You ask, "Hey, who moved the remote? Who left the milk out?" He can only shake his head, "I don't know. Maybe someone came in?" Life becomes unpredictable. A system with haphazardly managed state is exactly like that: unpredictable. And in the world of software, unpredictability is another name for a bug.
So, where are the most common mistaken assumptions?
First, we think state is passive. We think it's just storage. A database, a variable, a file. Just read and write. Actually, state is active. It has consequences. Changing one state value can trigger a chain of other events (side effects) like dominoes. For example, you set user.isLoggedIn = false. That's not just changing a boolean. It should also: cancel all pending requests, empty the shopping cart, redirect the page to login, and send a notification to the server. If you only change the boolean, the rest of the system's "memory" of what to do after logout is lost. Thus, a bug.
Second, we think state is singular and global. This is Rio's trap. One variable for everything. In reality, a good system often needs several separate, isolated "memories." State for UI (is the modal open?), state for business data (what's in the cart?), state for network (is anything loading?). Mixing them is a recipe for chaos. It's like mixing memories of a cooking recipe with memories of a meeting schedule. The result, you might cook chicken with an added "reminder: meeting at 3 PM." Not the expected flavor.
Third, and this is the most subtle: we forget that state has a history and context. State is not a static snapshot. It's a point in a timeline. An e-commerce transaction has a state: from 'cart', to 'checkout', to 'awaiting payment', to 'processing', to 'shipped'. Each of those states is only valid if the previous state was valid. You can't be in the 'shipped' state without ever going through 'awaiting payment'. Ignoring this history—due to a bug or a hack—means breaking fundamental business logic. The system might still run, but it's running in the wrong direction.
So, how do we manage this system "memory" correctly? There's no single answer, but the principle is similar to how we manage our own memory.
1. Set clear boundaries. Just as we have "working memory" for things we're currently working on, and "long-term memory" for knowledge. In code, this means separating a component's local state (working memory) from the application's global state (long-term memory). And don't arbitrarily access one another.
2. One entry point for changes. Our memory can be corrupted if too many people tell different versions of a story. In a system, state changes should go through one clear mechanism—usually via specific functions or methods (actions, mutations, reducers). Don't let any random line of code casually change isLoading = true. That's like letting strangers into your house to rearrange the furniture as they please.
3. Make its history traceable. When a bug occurs, the biggest question is: "How did the state get like this?" If every state change is logged, or even made immutable (cannot be changed directly, but must be replaced with a new copy), then we can step back and see the chronology. Like the "History" feature in Photoshop. It's extra work upfront, but saves hours of debugging later.
Managing state consciously also means accepting a fact: complexity doesn't disappear, it just moves. You can't eliminate logic complexity from an application that is inherently complex. What you can do is move that complexity from a messy place (like scattered all over the code) to a controlled place (like state management patterns: Redux, Vuex, or simpler ones like custom hooks).
In the end, I helped Rio tidy up his code. We moved all the scattered state into a single, clearly structured object. Then we created special functions solely responsible for changing that state. Nothing could change the state directly anymore. It had to go through a function. The process was like tidying a messy house: sorting, labeling, and assigning a place for everything.
The result? Those weird bugs decreased drastically. Not because the code became shorter—it actually added a few lines. But because the system now had an "organized memory." When the 'Save' button was disabled, we knew exactly why: because the isSubmitting state was true, and that value could only be changed by one function responsible for starting the submit process. Predictability increased. The developer's mental health too.
The big lesson is simple: the systems we build are creatures with memory. How we design that memory determines whether the system grows into a stable adult or remains a temperamental, unpredictable child.
Understanding that state is a living, ever-changing memory, not merely static storage, is one of the silent tasks that distinguishes a system that merely runs from one that is truly reliable.
FAQ: Q&A About State
Q: Is state the same as a database?
A: No. A database is persistent storage. State is the condition of the system in memory at that very moment. A database can be the source for filling initial state, but state can contain things not in the database (e.g., "is this dropdown open?").
Q: When should I use state management like Redux? It seems complicated.
A: When your state starts resembling a tangled thread involving many components not directly related. If you only need memory within one component (e.g., form input value), local state is enough. Redux is like a big office bulletin board—for information many departments need to know. Don't use it just for a personal shopping list.
Q> Why are state-related bugs often called "heisenbugs"?
A> Because, like Heisenberg's Uncertainty Principle in physics: the moment you try to observe it (debug), its behavior changes. For example, you console.log the state, and suddenly the bug disappears because the logging process slightly alters the execution timing. That's a hallmark of bugs related to timing and unmanaged state changes.
Q> What's the easiest everyday analogy for understanding state?
A> Look at an ATM. Its state: Has the card been inserted? Is the PIN correct? Is the balance sufficient? Which transaction is selected? Has the cash been dispensed? If you press "Cancel" mid-process, the ATM must remember which state to revert to (e.g., eject the card without dispensing cash). If its state is messed up, cash might come out even though the card was returned. Scary, right?
Q> Is immutable state mandatory?
A> Not mandatory, but highly, highly recommended. Imagine you have a document. It's safer to edit with "Save As" (create a new copy) than to overwrite the original file directly. If you make a mistake, you still have the old version. Immutable state provides the same guarantee of predictability.
Thank you for stopping by! If you enjoy the content and would like to show your support, how about treating me to a cup of coffee? �� It’s a small gesture that helps keep me motivated to continue creating awesome content. No pressure, but your coffee would definitely make my day a little brighter. ☕️ Buy Me Coffee

Post a Comment for "State: Bukan Cuma Data, Tapi Ingatan Sistem"
Post a Comment
You are welcome to share your ideas with us in comments!