Dalam satu kalimat
React adalah library JavaScript untuk membangun user interface dengan memecahnya menjadi bagian-bagian kode yang mandiri dan bisa dipakai ulang, yang disebut "komponen", yang secara otomatis di-update saat datanya berubah.
Masalah yang diselesaikan
Bayangin development web di zaman dulu (sekitar awal 2010-an). Kamu punya halaman web, dan kamu mau bikin jadi interaktif. Mungkin kamu mau tombol "suka" jadi biru dan angkanya nambah pas diklik. Pakai tool kayak jQuery, kamu bakal nulis kode yang bilang: "cari tombol di halaman, pantau event klik, dan pas diklik, cari elemen counter lalu ubah teksnya, terus cari ikon tombolnya dan ubah warnanya."
Ini adalah pendekatan imperatif. Kamu ngasih browser resep langkah demi langkah tentang cara mengubah halaman. Cara ini berhasil buat tombol suka. Tapi gimana kalau untuk feed media sosial lengkap dengan ratusan postingan, komentar, notifikasi, dan jendela chat live, yang semuanya update barengan? "Resep" tadi bakal jadi "kode spageti" yang ruwet. Perubahan di satu tempat bisa-bisa ngerusak bagian lain yang sama sekali nggak berhubungan. Menjaga UI tetap konsisten dengan data aplikasi itu perjuangan konstan yang rawan eror.
Facebook ngalamin mimpi buruk ini dalam skala besar. Pada tahun 2011, mereka menciptakan React untuk menyelesaikan masalah ini secara internal. React memperkenalkan model deklaratif. Alih-alih ngasih tahu browser gimana cara mengubah sesuatu, kamu cukup deskripsikan seperti apa tampilan UI untuk setiap state yang ada. Kamu mendeklarasikan: "Kalau postingan disukai, tombolnya harus biru dan angkanya 101. Kalau nggak disukai, tombolnya abu-abu dan angkanya 100." Udah, gitu aja. Pas state disukai berubah dari false ke true, React yang akan mencari cara paling efisien untuk meng-update tombol dan counter-nya. React yang ngurusin "gimananya", jadi kamu bisa fokus ke "apanya".
Pergeseran dari pemikiran imperatif ke deklaratif ini adalah sebuah revolusi. Hal ini membuat pembuatan UI yang kompleks dan berbasis data jadi lebih mudah diprediksi, diskalakan, dan di-debug.
Cara kerjanya di balik layar
"Sihir"-nya React itu sebenarnya bukan sihir; tapi kombinasi cerdas dari tiga ide inti: JSX, Komponen dengan State, dan Virtual DOM.
JSX: JavaScript dengan Pemanis Sintaks
Waktu kamu lihat kode React, kamu bakal nemuin sesuatu yang mirip banget sama HTML yang disematkan langsung di dalam JavaScript. Inilah JSX (JavaScript XML).
const greeting = <h1>Hello, FlowingDev user!</h1>;
Browser kamu nggak ngerti harus ngapain sama kode ini. Ini bukan JavaScript yang valid. Sebelum kode ini bisa jalan, kode ini perlu di-"transpile" (diubah) oleh tool seperti Babel. Baris JSX di atas akan diubah menjadi pemanggilan fungsi JavaScript biasa.
const greeting = React.createElement("h1", null, "Hello, FlowingDev user!");
Setiap tag JSX menjadi pemanggilan React.createElement(). Pemanggilan fungsi ini nggak membuat elemen HTML sungguhan. Ini membuat objek JavaScript ringan yang mendeskripsikan elemen yang ingin kamu buat—tipenya (h1), propertinya (nggak ada, jadi null), dan anak-anaknya ("Hello..."). Objek-objek inilah yang jadi blok pembangun Virtual DOM.
Jadi, JSX itu cuma "syntactic sugar" (pemanis sintaks). Kita bisa mendeskripsikan UI kita dengan sintaks mirip HTML yang familiar, tapi di balik layar, kita cuma membuat sebuah pohon (tree) dari objek JavaScript.
Komponen dan State: Otak dari Operasi
Komponen adalah fungsi JavaScript yang me-return JSX. Komponen adalah potongan UI yang bisa dipakai ulang dan mandiri.
function Greeting({ name }) {
return <h1>Hello, {name}!</h1>;
}
Komponen Greeting ini simpel. Dia nerima name sebagai input (disebut "prop") dan me-render sebuah heading. Tapi gimana kalau kita mau komponen bisa mengingat sesuatu dan berubah seiring waktu, seperti counter? Untuk itu, kita butuh "state."
State adalah data yang "dimiliki" oleh komponen dan bisa berubah. React menyediakan fungsi khusus yang disebut "hooks" untuk mengelolanya. Yang paling umum adalah useState.
import { useState } from 'react';
function Counter() {
// "count" adalah variabel state kita.
// "setCount" adalah *satu-satunya* fungsi yang bisa kita pakai untuk meng-update-nya.
const [count, setCount] = useState(0); // Nilai awalnya 0.
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Pas kamu manggil setCount(count + 1), kamu nggak cuma mengubah variabel. Kamu ngasih tahu React: "Woy, state untuk komponen Counter ini udah berubah. Tolong jalanin lagi fungsi ini buat dapetin UI barunya, terus update layarnya." React kemudian akan "me-render ulang" komponen, mendapatkan JSX baru dengan count yang sudah di-update, dan secara efisien memperbarui halaman web.
Virtual DOM: Senjata Rahasia React
Mengubah DOM browser asli (pohon elemen HTML yang live) secara langsung itu lambat. Ibaratnya kayak mendekorasi ulang ruangan dengan ngerobohin semua tembok dan bangun lagi, padahal kamu cuma mau mindahin bingkai foto.
React menghindari kerja mahal ini dengan senjata rahasianya: Virtual DOM (VDOM). VDOM hanyalah salinan DOM yang disimpan di memori JavaScript. Itulah pohon objek React.createElement yang kita bicarakan tadi.
Ini prosesnya, yang dikenal sebagai rekonsiliasi (reconciliation):
- Render Awal: Waktu
Counterpertama kali di-render, React membangun pohon VDOM yang mendeskripsikan sebuahdivberisipdengan teks "You clicked 0 times" dan sebuahbutton. Lalu React menggunakan ini untuk membuat elemen DOM asli di halaman. - Perubahan State: Kamu klik tombolnya.
setCount(1)dipanggil. - Render Ulang dan VDOM Baru: React menjalankan ulang fungsi
Counter. React membangun pohon VDOM yang baru. Pohon baru ini hampir identik dengan yang lama, tapipsekarang mendeskripsikan teks "You clicked 1 times". - Diffing: Algoritma "diffing" React membandingkan pohon VDOM baru dengan yang lama. Algoritma ini menelusuri keduanya dan menemukan perbedaannya. Dalam kasus ini, hanya ditemukan satu perbedaan: teks di dalam tag
<p>telah berubah. - Update Secara Batch: React mengambil satu perubahan kecil ini dan menerapkannya ke DOM asli. React nggak menyentuh
divataubutton; dia hanya meng-update teks darip.
Proses diff-and-patch ini luar biasa cepat. Dengan mengelompokkan update (batching) dan meminimalkan manipulasi langsung ke DOM asli yang lambat, React membuat UI terasa cepat dan responsif, bahkan ketika data kompleks berubah dengan cepat.
Cerita dari dunia nyata
Kasus Data Form yang Menghilang
Seorang developer junior ditugaskan untuk membuat form registrasi pengguna multi-langkah yang kompleks. Setiap langkah adalah komponen yang berbeda. Di satu titik, mereka butuh checkbox kecil di Langkah 2 untuk menampilkan field input tambahan secara kondisional. Mereka mengimplementasikannya, tapi tiba-tiba, muncul bug aneh: setiap kali pengguna mencentang checkbox itu, semua data yang telah mereka masukkan di Langkah 2 lenyap.
Biang keladinya adalah kesalahpahaman soal "keys." Untuk menampilkan field tambahan, si developer mengubah struktur JSX-nya dengan cara yang membuat React berpikir seluruh komponen form untuk Langkah 2 adalah komponen yang baru dan berbeda. Tanpa prop key yang stabil untuk mengidentifikasinya, React menghancurkan komponen lama (bersama dengan semua state-nya, yaitu input pengguna) dan memasang komponen baru sebagai gantinya.
Pelajaran yang bisa diambil: prop key bukan cuma untuk list. key adalah identitas stabil untuk sebuah komponen. Memahami bagaimana React menggunakan key untuk melacak komponen di antara render sangat penting untuk menjaga state dan menghindari reset yang tidak terduga.
Palu API Tanpa Batas
Sebuah tim sedang membangun dashboard yang menampilkan data saham live. Seorang developer menulis komponen untuk mengambil harga terbaru dari saham tertentu menggunakan hook useEffect. Kodenya kira-kira seperti ini:
useEffect(() => {
fetchStockPrice(stockSymbol).then(price => {
setPrice(price); // Update state dengan harga baru
});
}); // Waduh, nggak ada dependency array-nya!
Begitu komponen dimuat, aplikasi jadi macet, kipas laptop si developer berputar kencang, dan pemantauan jaringan menunjukkan ribuan request API identik dikirim setiap detik. Mereka telah menciptakan infinite loop. useEffect mengambil data dan memanggil setPrice. Update state tersebut menyebabkan komponen di-render ulang. Karena useEffect tidak punya dependency array, ia berjalan lagi setelah setiap render, mengambil data lagi, meng-update state lagi, menyebabkan render ulang lagi, dan begitu seterusnya selamanya.
Pelajaran yang bisa diambil: Hooks React seperti useEffect adalah alat yang powerful tapi butuh ketelitian. Kamu harus menyediakan "dependency array" untuk memberitahu React kapan harus menjalankan ulang effect-nya. Kalau tidak disertakan, itu berarti "jalankan setelah setiap render", yang merupakan resep jitu untuk bencana saat ada update state.
Kesalahan dan jebakan umum
- Mengubah state secara langsung (mutating state). Jangan pernah melakukan
myState.prop = 'value'ataumyArray.push('item'). Deteksi perubahan React bergantung pada identitas objek dan array. Saat kamu memanggilsetState, kamu harus menyediakan objek atau array yang baru (misalnya, pakai spread syntax...) agar React menyadari perubahannya. - Lupa pakai
keydi dalam list. Saat kamu me-render daftar item menggunakan.map(), kamu harus memberikan setiap elemenprop keyyang unik dan stabil (sepertiitem.id). Ini adalah cara algoritma diffing React bisa secara efisien melacak item mana yang berpindah, ditambahkan, atau dihapus. Menggunakan indeks array sebagai key adalah anti-pattern umum yang bisa menimbulkan bug. - Menganggap JSX itu sama kayak HTML. Mirip, tapi nggak sama. Kamu harus pakai
classNamebukanclass,htmlForbukanfor, dan camelCase untuk properti style (backgroundColorbukanbackground-color). Selain itu, semua tag harus ditutup, jadi gambar ditulis<img ... />, bukan<img>. - Menganggap hooks itu sihir. Hooks seperti
useStatedanuseEffectmengikuti aturan ketat (misalnya, hanya bisa dipanggil di level teratas dari sebuah function component). Mereka bekerja dengan mengandalkan urutan pemanggilan yang konsisten di antara render. Mencoba memanggilnya di dalam loop atau kondisi akan merusak aplikasimu.
Kenapa ini penting buat kamu tahu
React itu bukan cuma library; tapi sebuah ekosistem dan cara berpikir. React menggerakkan sebagian besar web modern, dari situs raksasa seperti Instagram dan Netflix hingga startup dan tool internal yang tak terhitung jumlahnya. Belajar React berarti belajar arsitektur berbasis komponen yang mendorong kode yang bisa dipakai ulang, mudah dites, dan gampang dirawat.
Bahkan jika kamu nggak menggunakan React setiap hari, memahami prinsip-prinsip intinya—UI deklaratif, manajemen state, dan VDOM—akan membuatmu menjadi developer yang lebih baik. Konsep-konsep ini telah memengaruhi hampir setiap framework UI modern lainnya, dari Vue hingga Svelte. Terlebih lagi, dengan React Native, skill dan prinsip yang sama bisa digunakan untuk membangun aplikasi mobile native untuk iOS dan Android. Ini adalah paradigma powerful yang esensial bagi developer mana pun yang bekerja dengan user interface saat ini.
Pelajari lebih dalam
- React Docs (Official) - Dokumentasi resminya adalah tempat terbaik untuk mulai, dengan tutorial komprehensif dan pembahasan mendalam.
- Introducing JSX (React Docs) - Penjelasan resmi soal JSX dan perbedaannya dari HTML.
- Reconciliation (React Docs) - Algoritma yang dipakai React untuk membandingkan dua VDOM tree dan meng-update UI secara efisien.
- The Rules of Hooks (React Docs) - Aturan-aturan penting yang harus kamu ikuti saat menggunakan hooks seperti
useStatedanuseEffect. - MDN: Introduction to the DOM - Untuk ngerti apa yang dimanipulasi React, penting banget buat paham Document Object Model itu sendiri.
Cara editor memahami kode
Warna berasal dari parser bahasa, bukan dari menjalankan program. CodeMirror dan Lezer mengenali token dan struktur secara lokal di browser. Saran menggabungkan kata kunci, nama lokal jika didukung, cuplikan dan referensi bawaan kecil; mengarahkan kursor ke simbol yang terdokumentasi menampilkan tanda tangannya. Saran bukan jaminan API tersedia di runtime. Diagnostik parser mendeteksi sintaks keliru jika didukung, tetapi tidak menggantikan pemeriksaan tipe atau eksekusi: sintaks valid tetap bisa gagal. Ruby dan Lua memakai mode berbasis token dengan diagnostik lebih terbatas. Tidak ada server bahasa jarak jauh; kode tetap di perangkat.
CodeMirror & Lezer: MIT.